diff --git a/cmd/tools/vls.v b/cmd/tools/vls.v index 9315d05793..2694621d89 100644 --- a/cmd/tools/vls.v +++ b/cmd/tools/vls.v @@ -154,8 +154,7 @@ fn (upd VlsUpdater) download_prebuilt() ! { } latest_release := releases_json[0].as_map() - latest_assets := latest_release['assets'] or { return } - assets := latest_assets.arr() + assets := latest_release['assets']!.arr() mut checksum_asset_idx := -1 mut exec_asset_idx := -1 @@ -199,13 +198,11 @@ fn (upd VlsUpdater) download_prebuilt() ! { upd.log('Executable found for this system. Downloading...') upd.init_download_prebuilt()! - t_asset := exec_asset['browser_download_url'] or { return } - http.download_file(t_asset.str(), exec_asset_file_path)! + http.download_file(exec_asset['browser_download_url']!.str(), exec_asset_file_path)! checksum_file_path := os.join_path(vls_cache_folder, 'checksums.txt') checksum_file_asset := assets[checksum_asset_idx].as_map() - t_checksum_asset := checksum_file_asset['browser_download_url'] or { return } - http.download_file(t_checksum_asset.str(), checksum_file_path)! + http.download_file(checksum_file_asset['browser_download_url']!.str(), checksum_file_path)! checksums := os.read_file(checksum_file_path)!.split_into_lines() upd.log('Verifying checksum...') diff --git a/doc/docs.md b/doc/docs.md index 6cec3714d0..c7121bae41 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -1290,7 +1290,7 @@ large_index := 999 val := arr[large_index] or { panic('out of bounds') } println(val) // you can also do this, if you want to *propagate* the access error: -val2 := arr[333]? +val2 := arr[333]! println(val2) ``` diff --git a/vlib/builtin/string_test.v b/vlib/builtin/string_test.v index 68e3d64b59..f869780cce 100644 --- a/vlib/builtin/string_test.v +++ b/vlib/builtin/string_test.v @@ -144,16 +144,16 @@ fn test_ranges() { assert s6 == 'first' } -fn ranges_propagate_first(s string) ?string { - return s[10..]? +fn ranges_propagate_first(s string) !string { + return s[10..]! } -fn ranges_propagate_last(s string) ?string { - return s[..20]? +fn ranges_propagate_last(s string) !string { + return s[..20]! } -fn ranges_propagate_both(s string) ?string { - return s[1..20]? +fn ranges_propagate_both(s string) !string { + return s[1..20]! } fn test_split_nth() { diff --git a/vlib/toml/tests/crlf_test.v b/vlib/toml/tests/crlf_test.v index 24c46ece02..f10eea4574 100644 --- a/vlib/toml/tests/crlf_test.v +++ b/vlib/toml/tests/crlf_test.v @@ -18,6 +18,6 @@ fn test_crlf_is_parsable_just_like_lf() { for content in all { res := toml.parse_text(content)? assert res.value('title') == toml.Any('TOML Example') - assert (res.value('database') as map[string]toml.Any)['server']? == toml.Any('192.168.1.1') + assert (res.value('database') as map[string]toml.Any)['server']! == toml.Any('192.168.1.1') } } diff --git a/vlib/v/ast/type_size_test.v b/vlib/v/ast/type_size_test.v index 4171cf1863..1821627068 100644 --- a/vlib/v/ast/type_size_test.v +++ b/vlib/v/ast/type_size_test.v @@ -41,21 +41,21 @@ fn test_type_size() { mut t := b.table - size01, _ := t.type_size(t.type_idxs['main.T01']?) + size01, _ := t.type_size(t.type_idxs['main.T01']!) assert sizeof(T01) == size01 - size02, _ := t.type_size(t.type_idxs['main.T02']?) + size02, _ := t.type_size(t.type_idxs['main.T02']!) assert sizeof(T02) == size02 - size03, _ := t.type_size(t.type_idxs['main.T03']?) + size03, _ := t.type_size(t.type_idxs['main.T03']!) assert sizeof(T03) == size03 - size04, _ := t.type_size(t.type_idxs['main.T04']?) + size04, _ := t.type_size(t.type_idxs['main.T04']!) assert sizeof(T04) == size04 - size05, _ := t.type_size(t.type_idxs['main.T05']?) + size05, _ := t.type_size(t.type_idxs['main.T05']!) assert sizeof(T05) == size05 - size06, _ := t.type_size(t.type_idxs['main.T06']?) + size06, _ := t.type_size(t.type_idxs['main.T06']!) assert sizeof(T06) == size06 - size07, _ := t.type_size(t.type_idxs['main.T07']?) + size07, _ := t.type_size(t.type_idxs['main.T07']!) assert sizeof(T07) == size07 - size08, _ := t.type_size(t.type_idxs['main.T08']?) + size08, _ := t.type_size(t.type_idxs['main.T08']!) assert sizeof(T08) == size08 println('done') diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 59303e9e3d..885050380e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -952,7 +952,7 @@ pub fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast } } else if expr is ast.IndexExpr { if expr.or_expr.kind != .absent { - c.check_or_expr(expr.or_expr, ret_type, ret_type.set_flag(.optional)) + c.check_or_expr(expr.or_expr, ret_type, ret_type.set_flag(.result)) } } return ret_type diff --git a/vlib/v/fmt/tests/empty_lines_keep.vv b/vlib/v/fmt/tests/empty_lines_keep.vv index 876716e083..a99b63bfba 100644 --- a/vlib/v/fmt/tests/empty_lines_keep.vv +++ b/vlib/v/fmt/tests/empty_lines_keep.vv @@ -92,7 +92,7 @@ bar' }, Two{ value: 'two' })" - r := m[key]? + r := m[key]! compile_time_env := $env('ENV_VAR') func() } diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index ad715ce362..bdd4f41135 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -2674,11 +2674,14 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr { is_gated: is_gated } } - // `a[start..end] ?` - if p.tok.kind == .question { + // `a[start..end]!` + if p.tok.kind == .not { or_pos_high = p.tok.pos() - or_kind_high = .propagate_option + or_kind_high = .propagate_result p.next() + } else if p.tok.kind == .question { + p.error_with_pos('`?` for propagating errors from index expressions is no longer supported, use `!` instead of `?`', + p.tok.pos()) } } @@ -2740,11 +2743,14 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr { is_gated: is_gated } } - // `a[start..end] ?` - if p.tok.kind == .question { + // `a[start..end]!` + if p.tok.kind == .not { or_pos_low = p.tok.pos() - or_kind_low = .propagate_option + or_kind_low = .propagate_result p.next() + } else if p.tok.kind == .question { + p.error_with_pos('`?` for propagating errors from index expressions is no longer supported, use `!` instead of `?`', + p.tok.pos()) } } @@ -2789,11 +2795,14 @@ fn (mut p Parser) index_expr(left ast.Expr, is_gated bool) ast.IndexExpr { is_gated: is_gated } } - // `a[i] ?` - if p.tok.kind == .question { + // `a[i]!` + if p.tok.kind == .not { or_pos = p.tok.pos() - or_kind = .propagate_option + or_kind = .propagate_result p.next() + } else if p.tok.kind == .question { + p.error_with_pos('`?` for propagating errors from index expressions is no longer supported, use `!` instead of `?`', + p.tok.pos()) } } return ast.IndexExpr{ diff --git a/vlib/v/parser/tests/index_expr_optional_err.out b/vlib/v/parser/tests/index_expr_optional_err.out new file mode 100644 index 0000000000..e91773916b --- /dev/null +++ b/vlib/v/parser/tests/index_expr_optional_err.out @@ -0,0 +1,6 @@ +vlib/v/parser/tests/index_expr_optional_err.vv:3:14: error: `?` for propagating errors from index expressions is no longer supported, use `!` instead of `?` + 1 | fn main() { + 2 | a := [1, 2] + 3 | println(a[0]?) + | ^ + 4 | } diff --git a/vlib/v/parser/tests/index_expr_optional_err.vv b/vlib/v/parser/tests/index_expr_optional_err.vv new file mode 100644 index 0000000000..f29bedbedb --- /dev/null +++ b/vlib/v/parser/tests/index_expr_optional_err.vv @@ -0,0 +1,4 @@ +fn main() { + a := [1, 2] + println(a[0]?) +} diff --git a/vlib/v/tests/array_map_or_test.v b/vlib/v/tests/array_map_or_test.v index 6e7142cc56..ee2d27b34f 100644 --- a/vlib/v/tests/array_map_or_test.v +++ b/vlib/v/tests/array_map_or_test.v @@ -51,26 +51,26 @@ fn test_map_or() { assert good == 5 } -fn get_map_el(key string) ?int { +fn get_map_el(key string) !int { m := { 'as': 3 'qw': 4 'kl': 5 } - r := m[key]? + r := m[key]! return r } -fn get_arr_el(i int) ?int { +fn get_arr_el(i int) !int { m := [3, 4, 5] - r := m[i]? + r := m[i]! return r } [direct_array_access] -fn get_arr_el_direct(i int) ?int { +fn get_arr_el_direct(i int) !int { m := [3, 4, 5] - r := m[i]? + r := m[i]! return r } @@ -105,10 +105,10 @@ fn test_propagation() { assert n == 3 } -fn get_arr_el_nested(i int) ?int { +fn get_arr_el_nested(i int) !int { ind := [2, 1, 0, 5] m := [3, 4, 5] - r := m[ind[i]]? + r := m[ind[i]]! return r } diff --git a/vlib/v/tests/map_init_with_multi_enum_keys_test.v b/vlib/v/tests/map_init_with_multi_enum_keys_test.v index 60f27a5ac8..9673287026 100644 --- a/vlib/v/tests/map_init_with_multi_enum_keys_test.v +++ b/vlib/v/tests/map_init_with_multi_enum_keys_test.v @@ -32,11 +32,11 @@ fn test_nested_map_init_with_multi_enum_keys() { } } println(mp) - assert mp[.a]? == NestedAbc({ + assert mp[.a]! == NestedAbc({ 'A': 'AA' }) - assert mp[.b]? == NestedAbc('B') - assert mp[.c]? == NestedAbc({ + assert mp[.b]! == NestedAbc('B') + assert mp[.c]! == NestedAbc({ 'c': 'C' }) } diff --git a/vlib/v/tests/nested_map_index_test.v b/vlib/v/tests/nested_map_index_test.v index fee6fc6383..34ffbd935c 100644 --- a/vlib/v/tests/nested_map_index_test.v +++ b/vlib/v/tests/nested_map_index_test.v @@ -18,7 +18,7 @@ fn test_nested_map_index() { } } } - ret := f.foo[11]?.bar[22]? + ret := f.foo[11]!.bar[22]! println(ret) assert ret == 'hello' } diff --git a/vlib/v/tests/string_index_or_test.v b/vlib/v/tests/string_index_or_test.v index f7c8611599..b0b0eeffa6 100644 --- a/vlib/v/tests/string_index_or_test.v +++ b/vlib/v/tests/string_index_or_test.v @@ -38,8 +38,8 @@ fn test_if_guard_good() { assert res == '1' } -fn get_propagate(s string, i int) ?string { - c := s[i]? +fn get_propagate(s string, i int) !string { + c := s[i]! return 'got `${c:c}`' }