all: improve unused variable warning (fix `x = 1`, `x += 1` etc)

pull/9855/head
Alexander Medvednikov 2021-04-23 13:33:48 +03:00
parent aa40dfc1de
commit c7a6d28e13
64 changed files with 199 additions and 141 deletions

View File

@ -1,14 +1,14 @@
@implementation MyView2 @implementation MyView2
int xx = 0; int __v_sokol_inited = 0;
// Alternative drawRect which calls a frame function with native Cocoa calls // Alternative drawRect which calls a frame function with native Cocoa calls
- (void)drawRect:(NSRect)rect { - (void)drawRect:(NSRect)rect {
puts("drawRect()"); //puts("drawRect()");
if (xx == 0) { if (__v_sokol_inited == 0) {
_sapp_call_init(); _sapp_call_init();
xx = 1; __v_sokol_inited = 1;
} }
_sapp_call_frame_native(); _sapp_call_frame_native();
} }

View File

@ -120,12 +120,11 @@ pub fn eprintln(s string) {
C.fprintf(C.stderr, c'%.*s\n', s.len, s.str) C.fprintf(C.stderr, c'%.*s\n', s.len, s.str)
} }
} $else { } $else {
mut n := 0
if s.str == 0 { if s.str == 0 {
n = C.write(2, c'eprintln(NIL)\n', 14) _ = C.write(2, c'eprintln(NIL)\n', 14)
} else { } else {
n = C.write(2, s.str, s.len) _ = C.write(2, s.str, s.len)
n = C.write(2, c'\n', 1) _ = C.write(2, c'\n', 1)
} }
} }
C.fflush(C.stderr) C.fflush(C.stderr)
@ -158,11 +157,10 @@ pub fn eprint(s string) {
C.fprintf(C.stderr, c'%.*s', s.len, s.str) C.fprintf(C.stderr, c'%.*s', s.len, s.str)
} }
} $else { } $else {
mut n := 0
if s.str == 0 { if s.str == 0 {
n = C.write(2, c'eprint(NIL)', 11) _ = C.write(2, c'eprint(NIL)', 11)
} else { } else {
n = C.write(2, s.str, s.len) _ = C.write(2, s.str, s.len)
} }
} }
C.fflush(C.stderr) C.fflush(C.stderr)
@ -172,7 +170,6 @@ pub fn eprint(s string) {
// print prints a message to stdout. Unlike `println` stdout is not automatically flushed. // print prints a message to stdout. Unlike `println` stdout is not automatically flushed.
// A call to `flush()` will flush the output buffer to stdout. // A call to `flush()` will flush the output buffer to stdout.
pub fn print(s string) { pub fn print(s string) {
mut n := 0
$if android { $if android {
C.fprintf(C.stdout, c'%.*s', s.len, s.str) C.fprintf(C.stdout, c'%.*s', s.len, s.str)
} $else $if ios { } $else $if ios {
@ -181,7 +178,7 @@ pub fn print(s string) {
} $else $if freestanding { } $else $if freestanding {
bare_print(s.str, u64(s.len)) bare_print(s.str, u64(s.len))
} $else { } $else {
n = C.write(1, s.str, s.len) _ = C.write(1, s.str, s.len)
} }
} }
@ -194,7 +191,6 @@ fn C.asl_log(voidptr, voidptr, int, charptr)
*/ */
// println prints a message with a line end, to stdout. stdout is flushed. // println prints a message with a line end, to stdout. stdout is flushed.
pub fn println(s string) { pub fn println(s string) {
mut n := 0
if s.str == 0 { if s.str == 0 {
$if android { $if android {
C.fprintf(C.stdout, c'println(NIL)\n') C.fprintf(C.stdout, c'println(NIL)\n')
@ -204,7 +200,7 @@ pub fn println(s string) {
bare_print(s.str, u64(s.len)) bare_print(s.str, u64(s.len))
bare_print(c'println(NIL)\n', 13) bare_print(c'println(NIL)\n', 13)
} $else { } $else {
n = C.write(1, c'println(NIL)\n', 13) _ = C.write(1, c'println(NIL)\n', 13)
} }
return return
} }
@ -216,8 +212,8 @@ pub fn println(s string) {
bare_print(s.str, u64(s.len)) bare_print(s.str, u64(s.len))
bare_print(c'\n', 1) bare_print(c'\n', 1)
} $else { } $else {
n = C.write(1, s.str, s.len) _ = C.write(1, s.str, s.len)
n = C.write(1, c'\n', 1) _ = C.write(1, c'\n', 1)
} }
} }

View File

@ -145,5 +145,6 @@ fn break_if_debugger_attached() {
unsafe { unsafe {
mut ptr := &voidptr(0) mut ptr := &voidptr(0)
*ptr = voidptr(0) *ptr = voidptr(0)
_ = ptr
} }
} }

View File

@ -740,11 +740,10 @@ pub fn is_link(path string) bool {
// chdir changes the current working directory to the new directory in `path`. // chdir changes the current working directory to the new directory in `path`.
pub fn chdir(path string) { pub fn chdir(path string) {
mut n := 0
$if windows { $if windows {
C._wchdir(path.to_wide()) C._wchdir(path.to_wide())
} $else { } $else {
n = C.chdir(&char(path.str)) _ = C.chdir(&char(path.str))
} }
} }

View File

@ -3,12 +3,11 @@ module os
fn C.setpgid(pid int, pgid int) int fn C.setpgid(pid int, pgid int) int
fn (mut p Process) unix_spawn_process() int { fn (mut p Process) unix_spawn_process() int {
mut n := 0
mut pipeset := [6]int{} mut pipeset := [6]int{}
if p.use_stdio_ctl { if p.use_stdio_ctl {
n = C.pipe(&pipeset[0]) // pipe read end 0 <- 1 pipe write end _ = C.pipe(&pipeset[0]) // pipe read end 0 <- 1 pipe write end
n = C.pipe(&pipeset[2]) // pipe read end 2 <- 3 pipe write end _ = C.pipe(&pipeset[2]) // pipe read end 2 <- 3 pipe write end
n = C.pipe(&pipeset[4]) // pipe read end 4 <- 5 pipe write end _ = C.pipe(&pipeset[4]) // pipe read end 4 <- 5 pipe write end
} }
pid := fork() pid := fork()
if pid != 0 { if pid != 0 {

View File

@ -33,10 +33,10 @@ pub fn (cf &CFlag) eval() string {
sparams := remainder[cflag.fexisting_literal.len + 1..].all_before(')') sparams := remainder[cflag.fexisting_literal.len + 1..].all_before(')')
i += sparams.len + cflag.fexisting_literal.len + 1 i += sparams.len + cflag.fexisting_literal.len + 1
svalues := sparams.replace(',', '\n').split_into_lines().map(it.trim(' \'"')) svalues := sparams.replace(',', '\n').split_into_lines().map(it.trim(' \'"'))
mut found_spath := '' // mut found_spath := ''
for spath in svalues { for spath in svalues {
if os.exists(spath) { if os.exists(spath) {
found_spath = spath // found_spath = spath
value += spath value += spath
continue cflag_eval_outer_loop continue cflag_eval_outer_loop
} }

View File

@ -119,7 +119,7 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
match obj { match obj {
ast.Var { ast.Var {
if !c.pref.is_repl { if !c.pref.is_repl {
if !obj.is_used && obj.name[0] != `_` { if !obj.is_used && obj.name[0] != `_` && !c.file.is_test {
c.warn('unused variable: `$obj.name`', obj.pos) c.warn('unused variable: `$obj.name`', obj.pos)
} }
} }
@ -2570,7 +2570,10 @@ pub fn (mut c Checker) selector_expr(mut selector_expr ast.SelectorExpr) ast.Typ
// //
c.using_new_err_struct = using_new_err_struct_save c.using_new_err_struct = using_new_err_struct_save
if typ == ast.void_type_idx { if typ == ast.void_type_idx {
c.error('unknown selector expression', selector_expr.pos) // This means that the variable's value was assigned to an
// unknown function or method, so the error was already handled
// earlier
// c.error('unknown selector expression', selector_expr.pos)
return ast.void_type return ast.void_type
} }
selector_expr.expr_type = typ selector_expr.expr_type = typ
@ -3644,7 +3647,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
fn (mut c Checker) assert_stmt(node ast.AssertStmt) { fn (mut c Checker) assert_stmt(node ast.AssertStmt) {
cur_exp_typ := c.expected_type cur_exp_typ := c.expected_type
assert_type := c.check_expr_opt_call(node.expr, c.expr(node.expr)) assert_type := c.check_expr_opt_call(node.expr, c.expr(node.expr))
if assert_type != ast.bool_type_idx { if assert_type != ast.bool_type_idx && assert_type != ast.void_type_idx {
atype_name := c.table.get_type_symbol(assert_type).name atype_name := c.table.get_type_symbol(assert_type).name
c.error('assert can be used only with `bool` expressions, but found `$atype_name` instead', c.error('assert can be used only with `bool` expressions, but found `$atype_name` instead',
node.pos) node.pos)
@ -4763,7 +4766,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) ast.Type {
} }
ast.Var { ast.Var {
// incase var was not marked as used yet (vweb tmpl) // incase var was not marked as used yet (vweb tmpl)
obj.is_used = true // obj.is_used = true
if ident.pos.pos < obj.pos.pos { if ident.pos.pos < obj.pos.pos {
c.error('undefined variable `$ident.name` (used before declaration)', c.error('undefined variable `$ident.name` (used before declaration)',
ident.pos) ident.pos)

View File

@ -10,10 +10,10 @@ vlib/v/checker/tests/array_or_map_assign_err.vv:5:5: error: use `array2 = array1
4 | mut a3 := []int{} 4 | mut a3 := []int{}
5 | a3 = a1 5 | a3 = a1
| ^ | ^
6 | 6 |
7 | m1 := {'one': 1} 7 | m1 := {'one': 1}
vlib/v/checker/tests/array_or_map_assign_err.vv:8:8: error: cannot copy map: call `move` or `clone` method (or use a reference) vlib/v/checker/tests/array_or_map_assign_err.vv:8:8: error: cannot copy map: call `move` or `clone` method (or use a reference)
6 | 6 |
7 | m1 := {'one': 1} 7 | m1 := {'one': 1}
8 | m2 := m1 8 | m2 := m1
| ~~ | ~~
@ -24,12 +24,12 @@ vlib/v/checker/tests/array_or_map_assign_err.vv:10:7: error: cannot copy map: ca
9 | mut m3 := map[string]int{} 9 | mut m3 := map[string]int{}
10 | m3 = m1 10 | m3 = m1
| ~~ | ~~
11 | 11 |
12 | _ = a2 12 | _ = a2
vlib/v/checker/tests/array_or_map_assign_err.vv:20:8: error: cannot copy map: call `move` or `clone` method (or use a reference) vlib/v/checker/tests/array_or_map_assign_err.vv:25:8: error: cannot copy map: call `move` or `clone` method (or use a reference)
18 | 23 |
19 | fn foo(mut m map[string]int) { 24 | fn foo(mut m map[string]int) {
20 | m2 := m 25 | m2 := m
| ^ | ^
21 | m['foo'] = 100 26 | m['foo'] = 100
22 | println(m) 27 | println(m)

View File

@ -14,6 +14,11 @@ fn main() {
mut m := {'foo':1} mut m := {'foo':1}
foo(mut m) foo(mut m)
_ = a3
_ = m1
_ = m2
_ = m3
} }
fn foo(mut m map[string]int) { fn foo(mut m map[string]int) {

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/arrow_op_wrong_left_type_err_b.vv:4:8: error: cannot assign
3 | mut obj := 9 3 | mut obj := 9
4 | obj = <-ch 4 | obj = <-ch
| ~~ | ~~
5 | } 5 | _ = obj
6 | }

View File

@ -2,4 +2,5 @@ fn main() {
ch := chan string{} ch := chan string{}
mut obj := 9 mut obj := 9
obj = <-ch obj = <-ch
_ = obj
} }

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/assign_expr_type_err_a.vv:3:2: error: operator <<= not defi
2 | mut foo := 0.5 2 | mut foo := 0.5
3 | foo <<= 1 3 | foo <<= 1
| ~~~ | ~~~
4 | } 4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
mut foo := 0.5 mut foo := 0.5
foo <<= 1 foo <<= 1
} _ = foo
}

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/assign_expr_type_err_b.vv:3:9: error: operator %= not defin
2 | mut foo := 10 2 | mut foo := 10
3 | foo %= 'hello' 3 | foo %= 'hello'
| ~~~~~~~ | ~~~~~~~
4 | } 4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
mut foo := 10 mut foo := 10
foo %= 'hello' foo %= 'hello'
} _ = foo
}

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/assign_expr_type_err_c.vv:3:2: error: operator *= not defin
2 | mut foo := 'hello' 2 | mut foo := 'hello'
3 | foo *= 10 3 | foo *= 10
| ~~~ | ~~~
4 | } 4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
mut foo := 'hello' mut foo := 'hello'
foo *= 10 foo *= 10
} _ = foo
}

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/assign_expr_type_err_d.vv:3:9: error: operator /= not defin
2 | mut foo := 1.5 2 | mut foo := 1.5
3 | foo /= true 3 | foo /= true
| ~~~~ | ~~~~
4 | } 4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
mut foo := 1.5 mut foo := 1.5
foo /= true foo /= true
} _ = foo
}

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/assign_expr_type_err_e.vv:3:2: error: operator `-=` not def
2 | mut foo := 'hello' 2 | mut foo := 'hello'
3 | foo -= `a` 3 | foo -= `a`
| ~~~ | ~~~
4 | } 4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
mut foo := 'hello' mut foo := 'hello'
foo -= `a` foo -= `a`
} _ = foo
}

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/assign_expr_type_err_f.vv:3:9: error: invalid right operand
2 | mut foo := 10 2 | mut foo := 10
3 | foo -= false 3 | foo -= false
| ~~~~~ | ~~~~~
4 | } 4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
mut foo := 10 mut foo := 10
foo -= false foo -= false
} _ = foo
}

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/assign_expr_type_err_g.vv:3:2: error: operator `+=` not def
2 | mut foo := true 2 | mut foo := true
3 | foo += false 3 | foo += false
| ~~~ | ~~~
4 | } 4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
mut foo := true mut foo := true
foo += false foo += false
} _ = foo
}

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/assign_expr_type_err_h.vv:3:9: error: invalid right operand
2 | mut foo := 'hello' 2 | mut foo := 'hello'
3 | foo += false 3 | foo += false
| ~~~~~ | ~~~~~
4 | } 4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
mut foo := 'hello' mut foo := 'hello'
foo += false foo += false
} _ = foo
}

View File

@ -1,6 +1,7 @@
vlib/v/checker/tests/assign_expr_type_err_i.vv:3:9: error: invalid right operand: f64 += string vlib/v/checker/tests/assign_expr_type_err_i.vv:3:9: error: invalid right operand: f64 += string
1 | fn main() { 1 | fn main() {
2 | mut foo := 1.5 2 | mut foo := 1.5
3 | foo += 'hello' 3 | foo += 'hello'
| ~~~~~~~ | ~~~~~~~
4 | } 4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
mut foo := 1.5 mut foo := 1.5
foo += 'hello' foo += 'hello'
} _ = foo
}

View File

@ -1,13 +1,13 @@
vlib/v/checker/tests/assign_expr_unresolved_variables_err_chain.vv:2:7: error: undefined variable `b` (used before declaration) vlib/v/checker/tests/assign_expr_unresolved_variables_err_chain.vv:2:7: error: undefined variable `b` (used before declaration)
1 | fn main() { 1 | fn main() {
2 | a := b 2 | a := b
| ^ | ^
3 | b := c 3 | b := c
4 | c := a 4 | c := a
vlib/v/checker/tests/assign_expr_unresolved_variables_err_chain.vv:3:7: error: undefined variable `c` (used before declaration) vlib/v/checker/tests/assign_expr_unresolved_variables_err_chain.vv:3:7: error: undefined variable `c` (used before declaration)
1 | fn main() { 1 | fn main() {
2 | a := b 2 | a := b
3 | b := c 3 | b := c
| ^ | ^
4 | c := a 4 | c := a
5 | } 5 | _ = a

View File

@ -2,4 +2,7 @@ fn main() {
a := b a := b
b := c b := c
c := a c := a
_ = a
_ = b
_ = c
} }

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/assign_sumtype_err.vv:13:9: error: cannot assign to `decl`:
12 | mut decl := Decl{} 12 | mut decl := Decl{}
13 | decl = stmt 13 | decl = stmt
| ~~~~ | ~~~~
14 | } 14 | _ = decl
15 | }

View File

@ -11,4 +11,5 @@ fn main() {
stmt := Stmt(Decl{}) stmt := Stmt(Decl{})
mut decl := Decl{} mut decl := Decl{}
decl = stmt decl = stmt
} _ = decl
}

View File

@ -11,10 +11,11 @@ vlib/v/checker/tests/enum_as_int_err.vv:10:8: error: cannot assign to `foo`: exp
10 | foo = Color.red 10 | foo = Color.red
| ~~~~~~~~~ | ~~~~~~~~~
11 | println(color == 0) 11 | println(color == 0)
12 | } 12 | _ = foo
vlib/v/checker/tests/enum_as_int_err.vv:11:10: error: infix expr: cannot use `int literal` (right expression) as `Color` vlib/v/checker/tests/enum_as_int_err.vv:11:10: error: infix expr: cannot use `int literal` (right expression) as `Color`
9 | color = 1 9 | color = 1
10 | foo = Color.red 10 | foo = Color.red
11 | println(color == 0) 11 | println(color == 0)
| ~~~~~~~~~~ | ~~~~~~~~~~
12 | } 12 | _ = foo
13 | }

View File

@ -9,4 +9,5 @@ fn main() {
color = 1 color = 1
foo = Color.red foo = Color.red
println(color == 0) println(color == 0)
_ = foo
} }

View File

@ -1,5 +1,5 @@
vlib/v/checker/tests/error_with_unicode.vv:5:17: error: cannot use `int literal` as `string` in argument 2 to `f1` vlib/v/checker/tests/error_with_unicode.vv:5:17: error: cannot use `int literal` as `string` in argument 2 to `f1`
3 | 3 |
4 | fn main() { 4 | fn main() {
5 | f1('🐀🐈', 0) 5 | f1('🐀🐈', 0)
| ^ | ^
@ -46,10 +46,11 @@ vlib/v/checker/tests/error_with_unicode.vv:12:6: error: cannot assign to `n`: ex
12 | n = '한글' 12 | n = '한글'
| ~~~~~~ | ~~~~~~
13 | n = 'Кириллица' 13 | n = 'Кириллица'
14 | } 14 | _ = n
vlib/v/checker/tests/error_with_unicode.vv:13:6: error: cannot assign to `n`: expected `int`, not `string` vlib/v/checker/tests/error_with_unicode.vv:13:6: error: cannot assign to `n`: expected `int`, not `string`
11 | n = '繁體字' 11 | n = '繁體字'
12 | n = '한글' 12 | n = '한글'
13 | n = 'Кириллица' 13 | n = 'Кириллица'
| ~~~~~~~~~~~ | ~~~~~~~~~~~
14 | } 14 | _ = n
15 | }

View File

@ -11,4 +11,5 @@ fn main() {
n = '' n = ''
n = '' n = ''
n = 'Кириллица' n = 'Кириллица'
_ = n
} }

View File

@ -11,31 +11,31 @@ vlib/v/checker/tests/fixed_array_conv.vv:5:4: error: mismatched types `&int` and
5 | ip = arr 5 | ip = arr
| ^ | ^
6 | _ = &int(arr) 6 | _ = &int(arr)
7 | 7 | _ = p
vlib/v/checker/tests/fixed_array_conv.vv:6:6: error: cannot cast a fixed array (use e.g. `&arr[0]` instead) vlib/v/checker/tests/fixed_array_conv.vv:6:6: error: cannot cast a fixed array (use e.g. `&arr[0]` instead)
4 | mut ip := &int(0) 4 | mut ip := &int(0)
5 | ip = arr 5 | ip = arr
6 | _ = &int(arr) 6 | _ = &int(arr)
| ~~~~~~~~ | ~~~~~~~~
7 | 7 | _ = p
8 | unsafe { 8 | _ = ip
vlib/v/checker/tests/fixed_array_conv.vv:9:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup` vlib/v/checker/tests/fixed_array_conv.vv:11:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup`
7 | 9 |
8 | unsafe { 10 | unsafe {
9 | _ = memdup(arr, 1) 11 | _ = memdup(arr, 1)
| ~~~ | ~~~
10 | _ = tos(arr, 1) 12 | _ = tos(arr, 1)
11 | fn (p &int){}(arr) 13 | fn (p &int){}(arr)
vlib/v/checker/tests/fixed_array_conv.vv:10:10: error: cannot use `[2]int` as `&byte` in argument 1 to `tos` vlib/v/checker/tests/fixed_array_conv.vv:12:10: error: cannot use `[2]int` as `&byte` in argument 1 to `tos`
8 | unsafe { 10 | unsafe {
9 | _ = memdup(arr, 1) 11 | _ = memdup(arr, 1)
10 | _ = tos(arr, 1) 12 | _ = tos(arr, 1)
| ~~~ | ~~~
11 | fn (p &int){}(arr) 13 | fn (p &int){}(arr)
12 | } 14 | }
vlib/v/checker/tests/fixed_array_conv.vv:11:16: error: cannot use `[2]int` as `&int` in argument 1 to `anon` vlib/v/checker/tests/fixed_array_conv.vv:13:16: error: cannot use `[2]int` as `&int` in argument 1 to `anon`
9 | _ = memdup(arr, 1) 11 | _ = memdup(arr, 1)
10 | _ = tos(arr, 1) 12 | _ = tos(arr, 1)
11 | fn (p &int){}(arr) 13 | fn (p &int){}(arr)
| ~~~ | ~~~
12 | } 14 | }

View File

@ -4,6 +4,8 @@ p = arr
mut ip := &int(0) mut ip := &int(0)
ip = arr ip = arr
_ = &int(arr) _ = &int(arr)
_ = p
_ = ip
unsafe { unsafe {
_ = memdup(arr, 1) _ = memdup(arr, 1)

View File

@ -14,10 +14,10 @@ vlib/v/checker/tests/fn_var.vv:4:5: error: cannot assign to `p`: expected `&fn (
3 | mut p := &f 3 | mut p := &f
4 | p = &[f] 4 | p = &[f]
| ^ | ^
5 | i := 0 5 | _ = p
6 | println(i) 6 | i := 0
vlib/v/checker/tests/fn_var.vv:7:31: error: undefined ident: `i` vlib/v/checker/tests/fn_var.vv:8:31: error: undefined ident: `i`
5 | i := 0 6 | i := 0
6 | println(i) 7 | println(i)
7 | f = fn(mut a []int) { println(i) } 8 | f = fn(mut a []int) { println(i) }
| ^ | ^

View File

@ -2,6 +2,7 @@ mut f := fn(i int) byte {}
f = 4 f = 4
mut p := &f mut p := &f
p = &[f] p = &[f]
_ = p
i := 0 i := 0
println(i) println(i)
f = fn(mut a []int) { println(i) } f = fn(mut a []int) { println(i) }

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/immutable_var.vv:3:2: error: `a` is immutable, declare it w
2 | a := 1 2 | a := 1
3 | a = 2 3 | a = 2
| ^ | ^
4 | } 4 | _ = a
5 | }

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
a := 1 a := 1
a = 2 a = 2
_ = a
} }

View File

@ -11,10 +11,11 @@ vlib/v/checker/tests/map_init_wrong_type.vv:4:17: error: invalid map key: expect
4 | _ = {2:0 3:0 "hi":0} 4 | _ = {2:0 3:0 "hi":0}
| ~~~~ | ~~~~
5 | _ = {2:0 3:`@` 4:0} 5 | _ = {2:0 3:`@` 4:0}
6 | } 6 | _ = a
vlib/v/checker/tests/map_init_wrong_type.vv:5:15: error: invalid map value: expected `int`, not `rune` vlib/v/checker/tests/map_init_wrong_type.vv:5:15: error: invalid map value: expected `int`, not `rune`
3 | a = { 'x': 12.3 } 3 | a = { 'x': 12.3 }
4 | _ = {2:0 3:0 "hi":0} 4 | _ = {2:0 3:0 "hi":0}
5 | _ = {2:0 3:`@` 4:0} 5 | _ = {2:0 3:`@` 4:0}
| ~~~ | ~~~
6 | } 6 | _ = a
7 | }

View File

@ -3,4 +3,5 @@ fn main() {
a = { 'x': 12.3 } a = { 'x': 12.3 }
_ = {2:0 3:0 "hi":0} _ = {2:0 3:0 "hi":0}
_ = {2:0 3:`@` 4:0} _ = {2:0 3:`@` 4:0}
_ = a
} }

View File

@ -46,25 +46,24 @@ vlib/v/checker/tests/method_op_err.vv:34:13: error: mismatched types `User` and
34 | println(User{3, 4} < Foo{3, 4}) 34 | println(User{3, 4} < Foo{3, 4})
| ~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~
35 | mut u := User{3, 4} 35 | mut u := User{3, 4}
36 | u += 12 36 | _ = u
vlib/v/checker/tests/method_op_err.vv:36:10: error: cannot assign to `u`: expected `User`, not `int literal` vlib/v/checker/tests/method_op_err.vv:37:10: error: cannot assign to `u`: expected `User`, not `int literal`
34 | println(User{3, 4} < Foo{3, 4})
35 | mut u := User{3, 4} 35 | mut u := User{3, 4}
36 | u += 12 36 | _ = u
37 | u += 12
| ~~ | ~~
37 | u %= User{1, 3} 38 | u %= User{1, 3}
38 | u += User{2, 3} 39 | u += User{2, 3}
vlib/v/checker/tests/method_op_err.vv:37:5: error: operator %= not defined on left operand type `User` vlib/v/checker/tests/method_op_err.vv:38:5: error: operator %= not defined on left operand type `User`
35 | mut u := User{3, 4} 36 | _ = u
36 | u += 12 37 | u += 12
37 | u %= User{1, 3} 38 | u %= User{1, 3}
| ^ | ^
38 | u += User{2, 3} 39 | u += User{2, 3}
39 | } 40 | }
vlib/v/checker/tests/method_op_err.vv:38:7: error: operator `+` must return `User` to be used as an assignment operator vlib/v/checker/tests/method_op_err.vv:39:7: error: operator `+` must return `User` to be used as an assignment operator
36 | u += 12 37 | u += 12
37 | u %= User{1, 3} 38 | u %= User{1, 3}
38 | u += User{2, 3} 39 | u += User{2, 3}
| ~~ | ~~
39 | } 40 | }

View File

@ -33,7 +33,8 @@ fn main() {
println(User{3, 2} < User{2, 4}) println(User{3, 2} < User{2, 4})
println(User{3, 4} < Foo{3, 4}) println(User{3, 4} < Foo{3, 4})
mut u := User{3, 4} mut u := User{3, 4}
_ = u
u += 12 u += 12
u %= User{1, 3} u %= User{1, 3}
u += User{2, 3} u += User{2, 3}
} }

View File

@ -3,3 +3,4 @@ vlib/v/checker/tests/ptr_assign.vv:3:5: error: cannot assign to `p`: expected `&
2 | mut p := &v 2 | mut p := &v
3 | p = 4 3 | p = 4
| ^ | ^
4 | _ = p

View File

@ -1,3 +1,4 @@
mut v := 43 mut v := 43
mut p := &v mut p := &v
p = 4 p = 4
_ = p

View File

@ -4,10 +4,11 @@ vlib/v/checker/tests/struct_assigned_to_pointer_to_struct.vv:5:4: error: mismatc
5 | f = { x: 223344 } 5 | f = { x: 223344 }
| ^ | ^
6 | f = Foo{ x: 20 } 6 | f = Foo{ x: 20 }
7 | } 7 | _ = f
vlib/v/checker/tests/struct_assigned_to_pointer_to_struct.vv:6:4: error: mismatched types `&Foo` and `Foo` vlib/v/checker/tests/struct_assigned_to_pointer_to_struct.vv:6:4: error: mismatched types `&Foo` and `Foo`
4 | mut f := &Foo{ 10 } 4 | mut f := &Foo{ 10 }
5 | f = { x: 223344 } 5 | f = { x: 223344 }
6 | f = Foo{ x: 20 } 6 | f = Foo{ x: 20 }
| ^ | ^
7 | } 7 | _ = f
8 | }

View File

@ -4,4 +4,5 @@ fn main() {
mut f := &Foo{ 10 } mut f := &Foo{ 10 }
f = { x: 223344 } f = { x: 223344 }
f = Foo{ x: 20 } f = Foo{ x: 20 }
_ = f
} }

View File

@ -13,7 +13,7 @@ vlib/v/checker/tests/sum.vv:6:8: error: cannot cast non-sum type `int` using `as
7 | } 7 | }
8 | 8 |
vlib/v/checker/tests/sum.vv:10:7: error: cannot cast `rune` to `Var` vlib/v/checker/tests/sum.vv:10:7: error: cannot cast `rune` to `Var`
8 | 8 |
9 | fn sum() { 9 | fn sum() {
10 | _ := Var(`J`) 10 | _ := Var(`J`)
| ~~~~~~~~ | ~~~~~~~~
@ -24,4 +24,5 @@ vlib/v/checker/tests/sum.vv:12:7: error: cannot assign to `s2`: expected `Var`,
11 | mut s2 := Var('') 11 | mut s2 := Var('')
12 | s2 = true 12 | s2 = true
| ~~~~ | ~~~~
13 | } 13 | _ = s2
14 | }

View File

@ -10,4 +10,5 @@ fn sum() {
_ := Var(`J`) _ := Var(`J`)
mut s2 := Var('') mut s2 := Var('')
s2 = true s2 = true
_ = s2
} }

View File

@ -3,4 +3,5 @@ vlib/v/checker/tests/sum_type_assign_non_variant_err.vv:11:6: error: cannot assi
10 | mut w := Stmt(AnotherThing{}) 10 | mut w := Stmt(AnotherThing{})
11 | w = IfExpr{} 11 | w = IfExpr{}
| ~~~~~~~~ | ~~~~~~~~
12 | } 12 | _ = w
13 | }

View File

@ -9,4 +9,5 @@ struct AnotherThing {}
fn main() { fn main() {
mut w := Stmt(AnotherThing{}) mut w := Stmt(AnotherThing{})
w = IfExpr{} w = IfExpr{}
_ = w
} }

View File

@ -1,6 +1,6 @@
vlib/v/checker/tests/var_used_before_declaration.vv:2:13: error: undefined variable `x` (used before declaration) vlib/v/checker/tests/var_used_before_declaration.vv:2:13: error: undefined variable `x` (used before declaration)
1 | fn main() { 1 | fn main() {
2 | println(x) 2 | println(x)
| ^ | ^
3 | x := 'hello v' 3 | x := 'hello v'
4 | } 4 | _ = x

View File

@ -1,4 +1,5 @@
fn main() { fn main() {
println(x) println(x)
x := 'hello v' x := 'hello v'
} _ = x
}

View File

@ -5,4 +5,5 @@ fn main() {
a += x('a','b') a += x('a','b')
mut b := 'abcdef' mut b := 'abcdef'
_ = b _ = b
_ = a
} }

View File

@ -1033,7 +1033,7 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
// this means this tmp expr var has already been freed // this means this tmp expr var has already been freed
continue continue
} }
obj.is_used = true obj.is_used = true // TODO bug? sets all vars is_used to true
g.autofree_variable(obj) g.autofree_variable(obj)
// g.nr_vars_to_free-- // g.nr_vars_to_free--
} }

View File

@ -1947,7 +1947,14 @@ pub fn (mut p Parser) name_expr() ast.Expr {
opt := if p.tok.lit == 'r' { '`r` (raw string)' } else { '`c` (c string)' } opt := if p.tok.lit == 'r' { '`r` (raw string)' } else { '`c` (c string)' }
return p.error('cannot use $opt with `byte` and `rune`') return p.error('cannot use $opt with `byte` and `rune`')
} }
known_var := p.mark_var_as_used(p.tok.lit) // Make sure that the var is not marked as used in assignments: `x = 1`, `x += 2` etc
// but only when it's actually used (e.g. `println(x)`)
known_var := if p.peek_tok.kind.is_assign() {
p.scope.known_var(p.tok.lit)
} else {
p.mark_var_as_used(p.tok.lit)
}
// Handle modules
mut is_mod_cast := false mut is_mod_cast := false
if p.peek_tok.kind == .dot && !known_var && (language != .v || p.known_import(p.tok.lit) if p.peek_tok.kind == .dot && !known_var && (language != .v || p.known_import(p.tok.lit)
|| p.mod.all_after_last('.') == p.tok.lit) { || p.mod.all_after_last('.') == p.tok.lit) {

View File

@ -4,14 +4,14 @@ vlib/v/parser/tests/prefix_first.vv:15:3: warning: move infix `-` operator befor
15 | -1 15 | -1
| ^ | ^
16 | } else {1} 16 | } else {1}
17 | } 17 | _ = p
vlib/v/parser/tests/prefix_first.vv:26:3: warning: move infix `&` operator before new line (if infix intended) or use brackets for a prefix expression vlib/v/parser/tests/prefix_first.vv:27:3: warning: move infix `&` operator before new line (if infix intended) or use brackets for a prefix expression
24 | _ = opt() or { 25 | _ = opt() or {
25 | _ = 1 26 | _ = 1
26 | &v 27 | &v
| ^ | ^
27 | } 28 | }
28 | } 29 | }
vlib/v/parser/tests/prefix_first.vv:13:6: error: `if` expression requires an expression as the last statement of every branch vlib/v/parser/tests/prefix_first.vv:13:6: error: `if` expression requires an expression as the last statement of every branch
11 | 11 |
12 | // later this should compile correctly 12 | // later this should compile correctly
@ -19,10 +19,10 @@ vlib/v/parser/tests/prefix_first.vv:13:6: error: `if` expression requires an exp
| ~~~~~~~ | ~~~~~~~
14 | v = 1 14 | v = 1
15 | -1 15 | -1
vlib/v/parser/tests/prefix_first.vv:24:12: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope vlib/v/parser/tests/prefix_first.vv:25:12: error: last statement in the `or {}` block should be an expression of type `&int` or exit parent scope
22 | // later this should compile correctly 23 | // later this should compile correctly
23 | v := 3 24 | v := 3
24 | _ = opt() or { 25 | _ = opt() or {
| ~~~~ | ~~~~
25 | _ = 1 26 | _ = 1
26 | &v 27 | &v

View File

@ -14,6 +14,7 @@ fn test_prefix() {
v = 1 v = 1
-1 -1
} else {1} } else {1}
_ = p
} }
fn opt() ?&int {return none} fn opt() ?&int {return none}

View File

@ -3,4 +3,5 @@ fn main() {
if mut x == 0 { if mut x == 0 {
println(true) println(true)
} }
_ = x
} }

View File

@ -93,7 +93,7 @@ pub fn (mut p Preferences) fill_with_defaults() {
} }
p.find_cc_if_cross_compiling() p.find_cc_if_cross_compiling()
p.ccompiler_type = cc_from_string(p.ccompiler) p.ccompiler_type = cc_from_string(p.ccompiler)
p.is_test = p.path.ends_with('_test.v') || p.path.ends_with('_test.vv') p.is_test = p.path.ends_with('_test.v') || p.path.ends_with('.vv') || p.path.ends_with('.vv')
|| p.path.all_before_last('.v').all_before_last('.').ends_with('_test') || p.path.all_before_last('.v').all_before_last('.').ends_with('_test')
p.is_vsh = p.path.ends_with('.vsh') p.is_vsh = p.path.ends_with('.vsh')
p.is_script = p.is_vsh || p.path.ends_with('.v') || p.path.ends_with('.vv') p.is_script = p.is_vsh || p.path.ends_with('.v') || p.path.ends_with('.vv')