From 11b7b973119f9025dc8ed268a1c41af08dd1f9f5 Mon Sep 17 00:00:00 2001 From: Enzo Baldisserri Date: Mon, 8 Jun 2020 00:47:04 +0200 Subject: [PATCH] parser: fail when assigning to _ with := --- cmd/tools/bench/wyhash.v | 6 +- cmd/tools/vup.v | 2 +- examples/vweb/vweb_example.v | 2 +- vlib/builtin/array_test.v | 2 +- vlib/crypto/aes/block_generic.v | 2 +- vlib/live/executable/reloader.v | 2 +- vlib/net/ftp/ftp.v | 4 +- vlib/net/socket.v | 6 +- vlib/net/socket_udp_test.v | 2 +- vlib/rand/random_numbers_test.v | 2 +- vlib/time/parse_test.v | 6 +- vlib/v/ast/ast.v | 8 --- vlib/v/checker/checker.v | 55 +++++++++++-------- vlib/v/checker/tests/blank_modify.out | 5 ++ vlib/v/checker/tests/blank_modify.vv | 3 + vlib/v/checker/tests/if_expr_last_stmt.out | 2 +- vlib/v/checker/tests/if_expr_last_stmt.vv | 2 +- vlib/v/checker/tests/if_expr_no_else.out | 6 +- vlib/v/checker/tests/if_expr_no_else.vv | 2 +- .../checker/tests/incorrect_name_variable.out | 2 +- .../checker/tests/incorrect_name_variable.vv | 2 +- vlib/v/checker/tests/match_expr_else.vv | 4 +- .../tests/no_interface_instantiation_a.out | 6 +- .../tests/no_interface_instantiation_a.vv | 2 +- vlib/v/checker/tests/selector_expr_assign.out | 6 ++ vlib/v/checker/tests/selector_expr_assign.vv | 8 +++ vlib/v/checker/tests/struct_unknown_field.out | 4 +- vlib/v/checker/tests/struct_unknown_field.vv | 8 +-- vlib/v/checker/tests/unexpected_or.out | 6 +- vlib/v/checker/tests/unexpected_or.vv | 2 +- vlib/v/checker/tests/void_fn_as_value.out | 12 ++-- vlib/v/checker/tests/void_fn_as_value.vv | 8 +-- vlib/v/checker/tests/void_optional_err.vv | 2 +- vlib/v/doc/doc.v | 2 +- vlib/v/gen/js/tests/js.v | 2 +- vlib/v/parser/assign.v | 12 ++-- vlib/v/parser/parser.v | 23 +++++--- vlib/v/table/table.v | 2 +- vlib/v/tests/array_init_test.v | 8 +-- vlib/v/tests/fn_high_test.v | 6 +- vlib/v/tests/vmod_parser_test.v | 2 +- 41 files changed, 137 insertions(+), 111 deletions(-) create mode 100644 vlib/v/checker/tests/blank_modify.out create mode 100644 vlib/v/checker/tests/blank_modify.vv create mode 100644 vlib/v/checker/tests/selector_expr_assign.out create mode 100644 vlib/v/checker/tests/selector_expr_assign.vv diff --git a/cmd/tools/bench/wyhash.v b/cmd/tools/bench/wyhash.v index 0f478914d2..203b83cbf2 100644 --- a/cmd/tools/bench/wyhash.v +++ b/cmd/tools/bench/wyhash.v @@ -24,7 +24,7 @@ fn main() { for len in str_lens { end_pos := start_pos + len str := string(bytepile[start_pos..end_pos],len) - _ = wyhash.wyhash_c(&str.str, u64(str.len), 1) + wyhash.wyhash_c(&str.str, u64(str.len), 1) start_pos = end_pos } t1 := time.ticks() @@ -34,7 +34,7 @@ fn main() { for len in str_lens { end_pos := start_pos + len str := string(bytepile[start_pos..end_pos],len) - _ = wyhash.sum64_string(str, 1) + wyhash.sum64_string(str, 1) start_pos = end_pos } t2 := time.ticks() @@ -44,7 +44,7 @@ fn main() { for len in str_lens { end_pos := start_pos + len str := string(bytepile[start_pos..end_pos],len) - _ = fnv1a.sum64_string(str) + fnv1a.sum64_string(str) start_pos = end_pos } t3 := time.ticks() diff --git a/cmd/tools/vup.v b/cmd/tools/vup.v index 6753031e61..8c8dcd8e78 100644 --- a/cmd/tools/vup.v +++ b/cmd/tools/vup.v @@ -56,7 +56,7 @@ fn main() { } } - _ := os.exec('v cmd/tools/vup.v') or { + os.exec('v cmd/tools/vup.v') or { panic(err) } show_current_v_version(vexe) diff --git a/examples/vweb/vweb_example.v b/examples/vweb/vweb_example.v index 657bdf2f7d..26e89a6841 100644 --- a/examples/vweb/vweb_example.v +++ b/examples/vweb/vweb_example.v @@ -27,7 +27,7 @@ pub fn (mut app App) json_endpoint() { pub fn (mut app App) index() { app.cnt++ - show:= true + show := true //app.vweb.text('Hello world from vweb') hello := 'Hello world from vweb' numbers := [1,2,3] diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index 62d35433dc..56de6422ec 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -593,7 +593,7 @@ fn test_array_str() { numbers := [1, 2, 3] assert numbers == [1,2,3] numbers2 := [numbers, [4, 5, 6]] // dup str() bug - _=numbers2 + _ = numbers2 assert true assert numbers.str() == '[1, 2, 3]' // QTODO diff --git a/vlib/crypto/aes/block_generic.v b/vlib/crypto/aes/block_generic.v index 6b63937917..cbeeda970d 100644 --- a/vlib/crypto/aes/block_generic.v +++ b/vlib/crypto/aes/block_generic.v @@ -84,7 +84,7 @@ fn encrypt_block_generic(xk []u32, dst, src []byte) { s2 ^= xk[k+2] s3 ^= xk[k+3] - _ = dst[15] // early bounds check + _ := dst[15] // early bounds check binary.big_endian_put_u32(mut dst[..4], s0) binary.big_endian_put_u32(mut dst.slice(4, 8), s1) binary.big_endian_put_u32(mut dst.slice(8, 12), s2) diff --git a/vlib/live/executable/reloader.v b/vlib/live/executable/reloader.v index ac17dc0243..0020852a01 100644 --- a/vlib/live/executable/reloader.v +++ b/vlib/live/executable/reloader.v @@ -36,7 +36,7 @@ pub fn start_reloader(mut r live.LiveReloadInfo) { // If that fails, the program would crash anyway, just provide // an error message to the user and exit: r.reloads++ - _ := compile_and_reload_shared_lib(mut r) or { + compile_and_reload_shared_lib(mut r) or { eprintln( err ) exit(1) } diff --git a/vlib/net/ftp/ftp.v b/vlib/net/ftp/ftp.v index f475b24df8..cd5c51b791 100644 --- a/vlib/net/ftp/ftp.v +++ b/vlib/net/ftp/ftp.v @@ -136,9 +136,7 @@ pub fn (ftp FTP) login(user, passwd string) bool { } return false } - code, data = ftp.read() - // TODO Replace `data` with `_` - _ := data + code, _ = ftp.read() if code == logged_in { return true } diff --git a/vlib/net/socket.v b/vlib/net/socket.v index c5c4325800..9c45972396 100644 --- a/vlib/net/socket.v +++ b/vlib/net/socket.v @@ -150,10 +150,10 @@ pub fn listen(port int) ?Socket { s := new_socket(C.AF_INET, C.SOCK_STREAM, 0) or { return error(err) } - _ = s.bind(port) or { + s.bind(port) or { return error(err) } - _ = s.listen() or { + s.listen() or { return error(err) } return s @@ -212,7 +212,7 @@ pub fn dial(address string, port int) ?Socket { s := new_socket(C.AF_INET, C.SOCK_STREAM, 0) or { return error(err) } - _ = s.connect(address, port) or { + s.connect(address, port) or { return error(err) } return s diff --git a/vlib/net/socket_udp_test.v b/vlib/net/socket_udp_test.v index c9fd5bfad4..165d6cde6b 100644 --- a/vlib/net/socket_udp_test.v +++ b/vlib/net/socket_udp_test.v @@ -4,7 +4,7 @@ fn start_socket_udp_server() { bufsize := 1024 bytes := [1024]byte s := net.socket_udp() or { panic(err) } - _ = s.bind( 9876 ) or { panic(err) } + s.bind( 9876 ) or { panic(err) } println('Waiting for udp packets:') for { res := s.crecv(bytes, bufsize) diff --git a/vlib/rand/random_numbers_test.v b/vlib/rand/random_numbers_test.v index bcebc2b237..fde6b0c576 100644 --- a/vlib/rand/random_numbers_test.v +++ b/vlib/rand/random_numbers_test.v @@ -26,7 +26,7 @@ fn test_rand_r_seed_update() { seed := 10 for _ in 0 .. rnd_count { prev_seed := seed - _ := rand.rand_r(&seed) + _ = rand.rand_r(&seed) assert prev_seed != seed } } diff --git a/vlib/time/parse_test.v b/vlib/time/parse_test.v index 4e2e184d79..e0df77f6aa 100644 --- a/vlib/time/parse_test.v +++ b/vlib/time/parse_test.v @@ -12,7 +12,7 @@ fn test_parse() { fn test_parse_invalid() { s := 'Invalid time string' - _ := time.parse(s) or { + time.parse(s) or { assert true return } @@ -38,7 +38,7 @@ fn test_parse_rfc2822() { fn test_parse_rfc2822_invalid() { s3 := 'Thu 12 Foo 2019 06:07:45 +0800' - _ := time.parse_rfc2822(s3) or { + time.parse_rfc2822(s3) or { assert true return } @@ -71,4 +71,4 @@ fn test_rfc8601_parse_cest() { assert t.minute == 38 assert t.second == 6 assert t.microsecond == 15959 -} \ No newline at end of file +} diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 4bab48d058..49eafd615f 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -801,14 +801,6 @@ pub fn expr_is_blank_ident(expr Expr) bool { } } -[inline] -pub fn expr_is_call(expr Expr) bool { - return match expr { - CallExpr { true } - else { false } - } -} - pub fn (expr Expr) position() token.Position { // all uncommented have to be implemented match mut expr { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index b932cfe411..7c0c8004ff 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -668,25 +668,36 @@ fn (mut c Checker) assign_expr(mut assign_expr ast.AssignExpr) { c.expected_type = table.void_type left_type := c.unwrap_generic(c.expr(assign_expr.left)) c.expected_type = left_type + if ast.expr_is_blank_ident(assign_expr.left) { + c.expected_type = table.Type(0) + } assign_expr.left_type = left_type // println('setting exp type to $c.expected_type $t.name') right_type := c.check_expr_opt_call(assign_expr.val, c.unwrap_generic(c.expr(assign_expr.val))) assign_expr.right_type = right_type right := c.table.get_type_symbol(right_type) left := c.table.get_type_symbol(left_type) - if ast.expr_is_blank_ident(assign_expr.left) { - return + match assign_expr.left { + ast.Ident { + if it.kind == .blank_ident { + if assign_expr.op != .assign { + + c.error('cannot modify blank `_` variable', it.pos) + } + return + } + } + ast.PrefixExpr { + // Do now allow `*x = y` outside `unsafe` + if it.op == .mul && !c.inside_unsafe { + c.error('modifying variables via deferencing can only be done in `unsafe` blocks', + assign_expr.pos) + } + } + else {} } // Make sure the variable is mutable c.fail_if_immutable(assign_expr.left) - // Do now allow `*x = y` outside `unsafe` - if assign_expr.left is ast.PrefixExpr { - p := assign_expr.left as ast.PrefixExpr - if p.op == .mul && !c.inside_unsafe { - c.error('modifying variables via deferencing can only be done in `unsafe` blocks', - assign_expr.pos) - } - } // Single side check match assign_expr.op { .assign {} // No need to do single side check for =. But here put it first for speed. @@ -1318,7 +1329,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { right_first := assign_stmt.right[0] mut right_len := assign_stmt.right.len if right_first is ast.CallExpr || right_first is ast.IfExpr || right_first is ast.MatchExpr { - right_type0 := c.expr(assign_stmt.right[0]) + right_type0 := c.expr(right_first) assign_stmt.right_types = [right_type0] right_type_sym0 := c.table.get_type_symbol(right_type0) if right_type0 == table.void_type { @@ -1332,12 +1343,11 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { call_expr := assign_stmt.right[0] as ast.CallExpr c.error('assignment mismatch: $assign_stmt.left.len variable(s) but `${call_expr.name}()` returns $right_len value(s)', assign_stmt.pos) - return } else { c.error('assignment mismatch: $assign_stmt.left.len variable(s) $right_len value(s)', assign_stmt.pos) - return } + return } } else if assign_stmt.left.len != right_len { c.error('assignment mismatch: $assign_stmt.left.len variable(s) $assign_stmt.right.len value(s)', @@ -1354,20 +1364,19 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) { c.check_expr_opt_call(assign_stmt.right[i], assign_stmt.right_types[i]) } mut val_type := assign_stmt.right_types[i] - // check variable name for beginning with capital letter 'Abc' - is_decl := assign_stmt.op == .decl_assign - if is_decl && ident.name != '_' { - c.check_valid_snake_case(ident.name, 'variable name', ident.pos) - } - if assign_stmt.op == .decl_assign { - val_type = c.table.mktyp(val_type) - } mut ident_var_info := ident.var_info() - if assign_stmt.op == .assign { + is_decl := assign_stmt.op == .decl_assign + if is_decl { + if ident.kind != .blank_ident { + // check variable name for beginning with capital letter 'Abc' + c.check_valid_snake_case(ident.name, 'variable name', ident.pos) + } + val_type = c.table.mktyp(val_type) + } else { c.fail_if_immutable(ident) var_type := c.expr(ident) assign_stmt.left_types << var_type - if !c.check_types(val_type, var_type) { + if ident.kind != .blank_ident && !c.check_types(val_type, var_type) { val_type_sym := c.table.get_type_symbol(val_type) var_type_sym := c.table.get_type_symbol(var_type) c.error('assign stmt: cannot use `$val_type_sym.name` as `$var_type_sym.name`', diff --git a/vlib/v/checker/tests/blank_modify.out b/vlib/v/checker/tests/blank_modify.out new file mode 100644 index 0000000000..12b7cc9552 --- /dev/null +++ b/vlib/v/checker/tests/blank_modify.out @@ -0,0 +1,5 @@ +vlib/v/checker/tests/blank_modify.v:2:2: error: cannot modify blank `_` variable + 1 | fn main() { + 2 | _ += 1 + | ^ + 3 | } diff --git a/vlib/v/checker/tests/blank_modify.vv b/vlib/v/checker/tests/blank_modify.vv new file mode 100644 index 0000000000..0a22021974 --- /dev/null +++ b/vlib/v/checker/tests/blank_modify.vv @@ -0,0 +1,3 @@ +fn main() { + _ += 1 +} diff --git a/vlib/v/checker/tests/if_expr_last_stmt.out b/vlib/v/checker/tests/if_expr_last_stmt.out index ab8ad293eb..f51ffdd5f9 100644 --- a/vlib/v/checker/tests/if_expr_last_stmt.out +++ b/vlib/v/checker/tests/if_expr_last_stmt.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/if_expr_last_stmt.v:4:7: error: `if` expression requires an expression as the last statement of every branch - 2 | _ := if true { + 2 | _ = if true { 3 | 1 4 | } else if false { | ~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/if_expr_last_stmt.vv b/vlib/v/checker/tests/if_expr_last_stmt.vv index beecb65c0c..eb5dd0c71d 100644 --- a/vlib/v/checker/tests/if_expr_last_stmt.vv +++ b/vlib/v/checker/tests/if_expr_last_stmt.vv @@ -1,5 +1,5 @@ fn main() { - _ := if true { + _ = if true { 1 } else if false { } else { diff --git a/vlib/v/checker/tests/if_expr_no_else.out b/vlib/v/checker/tests/if_expr_no_else.out index 17d5ad0ce3..c4d3306ca5 100644 --- a/vlib/v/checker/tests/if_expr_no_else.out +++ b/vlib/v/checker/tests/if_expr_no_else.out @@ -1,5 +1,5 @@ -vlib/v/checker/tests/if_expr_no_else.v:2:10: error: `if` expression needs `else` clause +vlib/v/checker/tests/if_expr_no_else.v:2:9: error: `if` expression needs `else` clause 1 | fn main() { - 2 | _ := if true { 1 } - | ~~ + 2 | _ = if true { 1 } + | ~~ 3 | } diff --git a/vlib/v/checker/tests/if_expr_no_else.vv b/vlib/v/checker/tests/if_expr_no_else.vv index d3e5144888..d416cc9457 100644 --- a/vlib/v/checker/tests/if_expr_no_else.vv +++ b/vlib/v/checker/tests/if_expr_no_else.vv @@ -1,3 +1,3 @@ fn main() { - _ := if true { 1 } + _ = if true { 1 } } diff --git a/vlib/v/checker/tests/incorrect_name_variable.out b/vlib/v/checker/tests/incorrect_name_variable.out index 87d31f561e..e4e7a1da47 100644 --- a/vlib/v/checker/tests/incorrect_name_variable.out +++ b/vlib/v/checker/tests/incorrect_name_variable.out @@ -2,5 +2,5 @@ vlib/v/checker/tests/incorrect_name_variable.v:2:2: error: variable name `_abc` 1 | fn main() { 2 | _abc := 1 | ~~~~ - 3 | _ := _abc + 3 | _ = _abc 4 | } \ No newline at end of file diff --git a/vlib/v/checker/tests/incorrect_name_variable.vv b/vlib/v/checker/tests/incorrect_name_variable.vv index dbbb549aeb..d4d42956e9 100644 --- a/vlib/v/checker/tests/incorrect_name_variable.vv +++ b/vlib/v/checker/tests/incorrect_name_variable.vv @@ -1,4 +1,4 @@ fn main() { _abc := 1 - _ := _abc + _ = _abc } diff --git a/vlib/v/checker/tests/match_expr_else.vv b/vlib/v/checker/tests/match_expr_else.vv index fff7be0253..af97dcf3da 100644 --- a/vlib/v/checker/tests/match_expr_else.vv +++ b/vlib/v/checker/tests/match_expr_else.vv @@ -10,7 +10,7 @@ fn main() { 'string' } } - _ := match x { + _ = match x { int { 'int' } @@ -24,7 +24,7 @@ fn main() { 'else' } } - _ := match x { + _ = match x { int { 'int' } diff --git a/vlib/v/checker/tests/no_interface_instantiation_a.out b/vlib/v/checker/tests/no_interface_instantiation_a.out index 2efdfb9dc8..0f553ee644 100644 --- a/vlib/v/checker/tests/no_interface_instantiation_a.out +++ b/vlib/v/checker/tests/no_interface_instantiation_a.out @@ -1,6 +1,6 @@ -vlib/v/checker/tests/no_interface_instantiation_a.v:4:10: error: cannot instantiate interface `Speaker` +vlib/v/checker/tests/no_interface_instantiation_a.v:4:9: error: cannot instantiate interface `Speaker` 2 | 3 | fn main() { - 4 | _ := Speaker{} - | ~~~~~~~~~ + 4 | _ = Speaker{} + | ~~~~~~~~~ 5 | } \ No newline at end of file diff --git a/vlib/v/checker/tests/no_interface_instantiation_a.vv b/vlib/v/checker/tests/no_interface_instantiation_a.vv index 52484b68ec..1d98644259 100644 --- a/vlib/v/checker/tests/no_interface_instantiation_a.vv +++ b/vlib/v/checker/tests/no_interface_instantiation_a.vv @@ -1,5 +1,5 @@ interface Speaker {} fn main() { - _ := Speaker{} + _ = Speaker{} } diff --git a/vlib/v/checker/tests/selector_expr_assign.out b/vlib/v/checker/tests/selector_expr_assign.out new file mode 100644 index 0000000000..ee7d7a9b7c --- /dev/null +++ b/vlib/v/checker/tests/selector_expr_assign.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/selector_expr_assign.v:7:6: error: struct fields can only be declared during the initialization + 5 | fn main() { + 6 | abc := Abc{} + 7 | abc.a := 2 + | ^ + 8 | } diff --git a/vlib/v/checker/tests/selector_expr_assign.vv b/vlib/v/checker/tests/selector_expr_assign.vv new file mode 100644 index 0000000000..024c869880 --- /dev/null +++ b/vlib/v/checker/tests/selector_expr_assign.vv @@ -0,0 +1,8 @@ +struct Abc { + a int +} + +fn main() { + abc := Abc{} + abc.a := 2 +} diff --git a/vlib/v/checker/tests/struct_unknown_field.out b/vlib/v/checker/tests/struct_unknown_field.out index 4b2893ef4f..8009084882 100644 --- a/vlib/v/checker/tests/struct_unknown_field.out +++ b/vlib/v/checker/tests/struct_unknown_field.out @@ -1,7 +1,7 @@ -vlib/v/checker/tests/struct_unknown_field.v:8:9: error: unknown field `bar` in struct literal of type `Test` +vlib/v/checker/tests/struct_unknown_field.v:8:3: error: unknown field `bar` in struct literal of type `Test` 6 | t := Test{ 7 | foo: true 8 | bar: false | ~~~~~~~~~~ 9 | } - 10 | _ = t + 10 | _ = t diff --git a/vlib/v/checker/tests/struct_unknown_field.vv b/vlib/v/checker/tests/struct_unknown_field.vv index e4ec496630..018bcefc87 100644 --- a/vlib/v/checker/tests/struct_unknown_field.vv +++ b/vlib/v/checker/tests/struct_unknown_field.vv @@ -4,8 +4,8 @@ struct Test { fn main() { t := Test{ - foo: true - bar: false - } - _ = t + foo: true + bar: false + } + _ = t } diff --git a/vlib/v/checker/tests/unexpected_or.out b/vlib/v/checker/tests/unexpected_or.out index 050750c9bf..f02adcb6b5 100644 --- a/vlib/v/checker/tests/unexpected_or.out +++ b/vlib/v/checker/tests/unexpected_or.out @@ -1,6 +1,6 @@ -vlib/v/checker/tests/unexpected_or.v:6:7: error: unexpected `or` block, the function `ret_zero` does not return an optional +vlib/v/checker/tests/unexpected_or.v:6:6: error: unexpected `or` block, the function `ret_zero` does not return an optional 4 | 5 | fn main() { - 6 | _ := ret_zero() or { 1 } - | ~~~~~~~~~~ + 6 | _ = ret_zero() or { 1 } + | ~~~~~~~~~~ 7 | } diff --git a/vlib/v/checker/tests/unexpected_or.vv b/vlib/v/checker/tests/unexpected_or.vv index 2ced3c9309..48a86968ec 100644 --- a/vlib/v/checker/tests/unexpected_or.vv +++ b/vlib/v/checker/tests/unexpected_or.vv @@ -3,5 +3,5 @@ fn ret_zero() int { } fn main() { - _ := ret_zero() or { 1 } + _ = ret_zero() or { 1 } } diff --git a/vlib/v/checker/tests/void_fn_as_value.out b/vlib/v/checker/tests/void_fn_as_value.out index f612c8abef..ce188c700b 100644 --- a/vlib/v/checker/tests/void_fn_as_value.out +++ b/vlib/v/checker/tests/void_fn_as_value.out @@ -1,7 +1,7 @@ -vlib/v/checker/tests/void_fn_as_value.v:5:8: error: unknown function: x +vlib/v/checker/tests/void_fn_as_value.v:5:7: error: unknown function: x 3 | fn main() { - 4 | mut a := 'aa' - 5 | a += x('a','b') - | ~~~~~~~~~~ - 6 | mut b := 'abcdef' - 7 | _ = b + 4 | mut a := 'aa' + 5 | a += x('a','b') + | ~~~~~~~~~~ + 6 | mut b := 'abcdef' + 7 | _ = b diff --git a/vlib/v/checker/tests/void_fn_as_value.vv b/vlib/v/checker/tests/void_fn_as_value.vv index 4d6f97dc39..1ab1394321 100644 --- a/vlib/v/checker/tests/void_fn_as_value.vv +++ b/vlib/v/checker/tests/void_fn_as_value.vv @@ -1,8 +1,8 @@ module main fn main() { - mut a := 'aa' - a += x('a','b') - mut b := 'abcdef' - _ = b + mut a := 'aa' + a += x('a','b') + mut b := 'abcdef' + _ = b } diff --git a/vlib/v/checker/tests/void_optional_err.vv b/vlib/v/checker/tests/void_optional_err.vv index ca812cc628..136e6e5adc 100644 --- a/vlib/v/checker/tests/void_optional_err.vv +++ b/vlib/v/checker/tests/void_optional_err.vv @@ -3,5 +3,5 @@ fn ret_void() ?void { } fn main() { - _ := ret_void() or { panic('$err') } + _ = ret_void() or { panic('$err') } } diff --git a/vlib/v/doc/doc.v b/vlib/v/doc/doc.v index 2bfcc6203c..3b6176cbe2 100644 --- a/vlib/v/doc/doc.v +++ b/vlib/v/doc/doc.v @@ -341,7 +341,7 @@ pub fn generate(input_path string, pub_only, with_comments bool) ?Doc { mut doc := new(input_path) doc.pub_only = pub_only doc.with_comments = with_comments - _ = doc.generate() or { + doc.generate() or { return error(err) } return doc diff --git a/vlib/v/gen/js/tests/js.v b/vlib/v/gen/js/tests/js.v index 10795dfe83..c9a5f14281 100644 --- a/vlib/v/gen/js/tests/js.v +++ b/vlib/v/gen/js/tests/js.v @@ -48,7 +48,7 @@ fn main() { v := "done" { - _ := "block" + _ = "block" } pos := POSITION.go_back diff --git a/vlib/v/parser/assign.v b/vlib/v/parser/assign.v index 6917b819a3..46d77827de 100644 --- a/vlib/v/parser/assign.v +++ b/vlib/v/parser/assign.v @@ -92,8 +92,7 @@ fn (mut p Parser) partial_assign_stmt(known_lhs []ast.Ident) ast.Stmt { } } for i, ident in idents { - known_var := p.scope.known_var(ident.name) - if !is_decl && !known_var { + if !is_decl && ident.kind != .blank_ident && !p.scope.known_var(ident.name) { p.error('unknown variable `$ident.name`') } if is_decl && ident.kind != .blank_ident { @@ -132,12 +131,9 @@ pub fn (mut p Parser) assign_expr(left ast.Expr) ast.AssignExpr { pos := p.tok.position() p.next() val := p.expr(0) - match left { - ast.IndexExpr { - // it.mark_as_setter() - it.is_setter = true - } - else {} + if left is ast.IndexExpr { + mut index_expr := left as ast.IndexExpr + index_expr.is_setter = true } node := ast.AssignExpr{ left: left diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 3ed4e47955..7e6485ca9b 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -729,7 +729,17 @@ fn (mut p Parser) parse_multi_expr() ast.Stmt { if p.tok.kind == .decl_assign || (p.tok.kind == .assign && collected.len > 1) { mut idents := []ast.Ident{} for c in collected { - idents << c as ast.Ident + match c { + ast.Ident { + idents << it + } + ast.SelectorExpr { + p.error_with_pos('struct fields can only be declared during the initialization', it.pos) + } + else { + p.error_with_pos('unexpected `${typeof(c)}`', c.position()) + } + } } return p.partial_assign_stmt(idents) } else if p.tok.kind.is_assign() { @@ -789,19 +799,18 @@ pub fn (mut p Parser) parse_ident(language table.Language) ast.Ident { if p.expr_mod.len > 0 { name = '${p.expr_mod}.$name' } - mut ident := ast.Ident{ + return ast.Ident{ kind: .unresolved name: name language: language mod: p.mod pos: pos - } - ident.is_mut = is_mut - ident.info = ast.IdentVar{ is_mut: is_mut - is_static: is_static + info: ast.IdentVar{ + is_mut: is_mut + is_static: is_static + } } - return ident } else { p.error('unexpected token `$p.tok.lit`') } diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index e10aec8f01..247ef093a2 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -264,7 +264,7 @@ pub fn (mut t Table) register_type_symbol(typ TypeSymbol) int { } pub fn (t &Table) known_type(name string) bool { - _ = t.find_type(name) or { + t.find_type(name) or { return false } return true diff --git a/vlib/v/tests/array_init_test.v b/vlib/v/tests/array_init_test.v index 4209f7651c..d72f6cc5f8 100644 --- a/vlib/v/tests/array_init_test.v +++ b/vlib/v/tests/array_init_test.v @@ -66,7 +66,7 @@ fn test_array_int_full_options() { assert a.str() == "[0, 0]" b := []int{len: 10, cap: 100, init: 1} // this creates an array with 10 one and initial capacity 100 elements, value given - _ := b.clone() // discard result variable, sample + _ = b.clone() // discard result variable, sample println('array b: length: ${b.len}, capacity: ${b.cap}, content: $b') assert b.len == 10 assert b.cap == 100 @@ -74,7 +74,7 @@ fn test_array_int_full_options() { assert b.str() == "[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]" mut c := []int{len: 2, cap: 10, init: 1} // this creates an array with 2 one and initial capacity 10 elements, value given - _ := c.clone() // discard result variable, sample + _ = c.clone() // discard result variable, sample println('array c: length: ${c.len}, capacity: ${c.cap}, content: $c') assert c.len == 2 assert c.cap == 10 @@ -109,7 +109,7 @@ fn test_array_string_full_options() { assert a.str() == "['', '']" b := []string{len: 10, cap: 100, init: 'b'} // this creates an array with 10 'b', initial capacity 100 elements, value given - _ := b.clone() // discard result variable, sample + _ = b.clone() // discard result variable, sample println('array b: length: ${b.len}, capacity: ${b.cap}') // ok println('array b: length: ${b.len}, capacity: ${b.cap}, content: $b') assert b.len == 10 @@ -118,7 +118,7 @@ fn test_array_string_full_options() { assert b.str() == "['b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'b']" mut c := []string{len: 2, cap: 10, init: 'c'} // this creates an array with 2 'c' and initial capacity 10 elements, value given - _ := c.clone() // discard result variable, sample + _ = c.clone() // discard result variable, sample println('array c: length: ${c.len}, capacity: ${c.cap}, content: $c') assert c.len == 2 assert c.cap == 10 diff --git a/vlib/v/tests/fn_high_test.v b/vlib/v/tests/fn_high_test.v index 8f70aa4982..0cbdb4db80 100644 --- a/vlib/v/tests/fn_high_test.v +++ b/vlib/v/tests/fn_high_test.v @@ -21,7 +21,7 @@ fn high_fn_multi_return(a int, b fn (c []int, d []string) ([]int, []string)) { } fn high_fn_return_single_anon() (fn(int)f32) { - _ := 1 + _ = 1 correct := fn(n int)f32 { return f32(n * n) } @@ -29,7 +29,7 @@ fn high_fn_return_single_anon() (fn(int)f32) { } fn high_fn_return_multi_anons() (fn(int)f32, fn(int)string) { // parsing trap - _ := fn(n int)byte { + _ = fn(n int)byte { return 0x00 } correct_second := fn(n int)string { @@ -39,7 +39,7 @@ fn high_fn_return_multi_anons() (fn(int)f32, fn(int)string) { return f32(n * n) } // parsing trap - _ := fn(n int)[]int { + _ = fn(n int)[]int { return [n] } return correct_first, correct_second diff --git a/vlib/v/tests/vmod_parser_test.v b/vlib/v/tests/vmod_parser_test.v index 3a4a85b846..c7168297c3 100644 --- a/vlib/v/tests/vmod_parser_test.v +++ b/vlib/v/tests/vmod_parser_test.v @@ -35,7 +35,7 @@ fn test_decode() { assert data.license == 'GPL-2.0' assert data.dependencies[0] == 'hello' assert data.unknown['test'][0] == 'foo' - _ := vmod.decode('') or { + vmod.decode('') or { assert err == 'vmod: no content.' exit(0) }