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
int xx = 0;
int __v_sokol_inited = 0;
// Alternative drawRect which calls a frame function with native Cocoa calls
- (void)drawRect:(NSRect)rect {
puts("drawRect()");
if (xx == 0) {
//puts("drawRect()");
if (__v_sokol_inited == 0) {
_sapp_call_init();
xx = 1;
__v_sokol_inited = 1;
}
_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)
}
} $else {
mut n := 0
if s.str == 0 {
n = C.write(2, c'eprintln(NIL)\n', 14)
_ = C.write(2, c'eprintln(NIL)\n', 14)
} else {
n = C.write(2, s.str, s.len)
n = C.write(2, c'\n', 1)
_ = C.write(2, s.str, s.len)
_ = C.write(2, c'\n', 1)
}
}
C.fflush(C.stderr)
@ -158,11 +157,10 @@ pub fn eprint(s string) {
C.fprintf(C.stderr, c'%.*s', s.len, s.str)
}
} $else {
mut n := 0
if s.str == 0 {
n = C.write(2, c'eprint(NIL)', 11)
_ = C.write(2, c'eprint(NIL)', 11)
} else {
n = C.write(2, s.str, s.len)
_ = C.write(2, s.str, s.len)
}
}
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.
// A call to `flush()` will flush the output buffer to stdout.
pub fn print(s string) {
mut n := 0
$if android {
C.fprintf(C.stdout, c'%.*s', s.len, s.str)
} $else $if ios {
@ -181,7 +178,7 @@ pub fn print(s string) {
} $else $if freestanding {
bare_print(s.str, u64(s.len))
} $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.
pub fn println(s string) {
mut n := 0
if s.str == 0 {
$if android {
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(c'println(NIL)\n', 13)
} $else {
n = C.write(1, c'println(NIL)\n', 13)
_ = C.write(1, c'println(NIL)\n', 13)
}
return
}
@ -216,8 +212,8 @@ pub fn println(s string) {
bare_print(s.str, u64(s.len))
bare_print(c'\n', 1)
} $else {
n = C.write(1, s.str, s.len)
n = C.write(1, c'\n', 1)
_ = C.write(1, s.str, s.len)
_ = C.write(1, c'\n', 1)
}
}

View File

@ -145,5 +145,6 @@ fn break_if_debugger_attached() {
unsafe {
mut 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`.
pub fn chdir(path string) {
mut n := 0
$if windows {
C._wchdir(path.to_wide())
} $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 (mut p Process) unix_spawn_process() int {
mut n := 0
mut pipeset := [6]int{}
if p.use_stdio_ctl {
n = 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
n = C.pipe(&pipeset[4]) // pipe read end 4 <- 5 pipe write end
_ = C.pipe(&pipeset[0]) // pipe read end 0 <- 1 pipe write end
_ = C.pipe(&pipeset[2]) // pipe read end 2 <- 3 pipe write end
_ = C.pipe(&pipeset[4]) // pipe read end 4 <- 5 pipe write end
}
pid := fork()
if pid != 0 {

View File

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

View File

@ -119,7 +119,7 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
match obj {
ast.Var {
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)
}
}
@ -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
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
}
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) {
cur_exp_typ := c.expected_type
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
c.error('assert can be used only with `bool` expressions, but found `$atype_name` instead',
node.pos)
@ -4763,7 +4766,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) ast.Type {
}
ast.Var {
// 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 {
c.error('undefined variable `$ident.name` (used before declaration)',
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{}
5 | a3 = a1
| ^
6 |
6 |
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)
6 |
6 |
7 | m1 := {'one': 1}
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{}
10 | m3 = m1
| ~~
11 |
11 |
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)
18 |
19 | fn foo(mut m map[string]int) {
20 | m2 := m
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)
23 |
24 | fn foo(mut m map[string]int) {
25 | m2 := m
| ^
21 | m['foo'] = 100
22 | println(m)
26 | m['foo'] = 100
27 | println(m)

View File

@ -14,6 +14,11 @@ fn main() {
mut m := {'foo':1}
foo(mut m)
_ = a3
_ = m1
_ = m2
_ = m3
}
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
4 | obj = <-ch
| ~~
5 | }
5 | _ = obj
6 | }

View File

@ -2,4 +2,5 @@ fn main() {
ch := chan string{}
mut obj := 9
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
3 | foo <<= 1
| ~~~
4 | }
4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
mut foo := 0.5
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
3 | foo %= 'hello'
| ~~~~~~~
4 | }
4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
mut foo := 10
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'
3 | foo *= 10
| ~~~
4 | }
4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
mut foo := 'hello'
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
3 | foo /= true
| ~~~~
4 | }
4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
mut foo := 1.5
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'
3 | foo -= `a`
| ~~~
4 | }
4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
mut foo := 'hello'
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
3 | foo -= false
| ~~~~~
4 | }
4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
mut foo := 10
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
3 | foo += false
| ~~~
4 | }
4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
mut foo := true
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'
3 | foo += false
| ~~~~~
4 | }
4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
mut foo := 'hello'
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
1 | fn main() {
2 | mut foo := 1.5
3 | foo += 'hello'
3 | foo += 'hello'
| ~~~~~~~
4 | }
4 | _ = foo
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
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() {
2 | a := b
| ^
3 | b := c
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() {
2 | a := b
3 | b := c
| ^
4 | c := a
5 | }
5 | _ = a

View File

@ -2,4 +2,7 @@ fn main() {
a := b
b := c
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{}
13 | decl = stmt
| ~~~~
14 | }
14 | _ = decl
15 | }

View File

@ -11,4 +11,5 @@ fn main() {
stmt := Stmt(Decl{})
mut decl := Decl{}
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
| ~~~~~~~~~
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`
9 | color = 1
10 | foo = Color.red
11 | println(color == 0)
| ~~~~~~~~~~
12 | }
12 | _ = foo
13 | }

View File

@ -9,4 +9,5 @@ fn main() {
color = 1
foo = Color.red
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`
3 |
3 |
4 | fn main() {
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 = '한글'
| ~~~~~~
13 | n = 'Кириллица'
14 | }
14 | _ = n
vlib/v/checker/tests/error_with_unicode.vv:13:6: error: cannot assign to `n`: expected `int`, not `string`
11 | n = '繁體字'
12 | n = '한글'
13 | n = 'Кириллица'
| ~~~~~~~~~~~
14 | }
14 | _ = n
15 | }

View File

@ -11,4 +11,5 @@ fn main() {
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
| ^
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)
4 | mut ip := &int(0)
5 | ip = arr
6 | _ = &int(arr)
| ~~~~~~~~
7 |
8 | unsafe {
vlib/v/checker/tests/fixed_array_conv.vv:9:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup`
7 |
8 | unsafe {
9 | _ = memdup(arr, 1)
7 | _ = p
8 | _ = ip
vlib/v/checker/tests/fixed_array_conv.vv:11:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup`
9 |
10 | unsafe {
11 | _ = memdup(arr, 1)
| ~~~
10 | _ = tos(arr, 1)
11 | 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`
8 | unsafe {
9 | _ = memdup(arr, 1)
10 | _ = tos(arr, 1)
12 | _ = tos(arr, 1)
13 | fn (p &int){}(arr)
vlib/v/checker/tests/fixed_array_conv.vv:12:10: error: cannot use `[2]int` as `&byte` in argument 1 to `tos`
10 | unsafe {
11 | _ = memdup(arr, 1)
12 | _ = tos(arr, 1)
| ~~~
11 | fn (p &int){}(arr)
12 | }
vlib/v/checker/tests/fixed_array_conv.vv:11:16: error: cannot use `[2]int` as `&int` in argument 1 to `anon`
9 | _ = memdup(arr, 1)
10 | _ = tos(arr, 1)
11 | fn (p &int){}(arr)
13 | fn (p &int){}(arr)
14 | }
vlib/v/checker/tests/fixed_array_conv.vv:13:16: error: cannot use `[2]int` as `&int` in argument 1 to `anon`
11 | _ = memdup(arr, 1)
12 | _ = tos(arr, 1)
13 | fn (p &int){}(arr)
| ~~~
12 | }
14 | }

View File

@ -4,6 +4,8 @@ p = arr
mut ip := &int(0)
ip = arr
_ = &int(arr)
_ = p
_ = ip
unsafe {
_ = 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
4 | p = &[f]
| ^
5 | i := 0
6 | println(i)
vlib/v/checker/tests/fn_var.vv:7:31: error: undefined ident: `i`
5 | i := 0
6 | println(i)
7 | f = fn(mut a []int) { println(i) }
5 | _ = p
6 | i := 0
vlib/v/checker/tests/fn_var.vv:8:31: error: undefined ident: `i`
6 | i := 0
7 | println(i)
8 | f = fn(mut a []int) { println(i) }
| ^

View File

@ -2,6 +2,7 @@ mut f := fn(i int) byte {}
f = 4
mut p := &f
p = &[f]
_ = p
i := 0
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
3 | a = 2
| ^
4 | }
4 | _ = a
5 | }

View File

@ -1,4 +1,5 @@
fn main() {
a := 1
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}
| ~~~~
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`
3 | a = { 'x': 12.3 }
4 | _ = {2:0 3:0 "hi":0}
5 | _ = {2:0 3:`@` 4:0}
| ~~~
6 | }
6 | _ = a
7 | }

View File

@ -3,4 +3,5 @@ fn main() {
a = { 'x': 12.3 }
_ = {2:0 3:0 "hi":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})
| ~~~~~~~~~~~~~~~~~~~~~~
35 | mut u := User{3, 4}
36 | u += 12
vlib/v/checker/tests/method_op_err.vv:36:10: error: cannot assign to `u`: expected `User`, not `int literal`
34 | println(User{3, 4} < Foo{3, 4})
36 | _ = u
vlib/v/checker/tests/method_op_err.vv:37:10: error: cannot assign to `u`: expected `User`, not `int literal`
35 | mut u := User{3, 4}
36 | u += 12
36 | _ = u
37 | u += 12
| ~~
37 | u %= User{1, 3}
38 | u += User{2, 3}
vlib/v/checker/tests/method_op_err.vv:37:5: error: operator %= not defined on left operand type `User`
35 | mut u := User{3, 4}
36 | u += 12
37 | u %= User{1, 3}
38 | u %= User{1, 3}
39 | u += User{2, 3}
vlib/v/checker/tests/method_op_err.vv:38:5: error: operator %= not defined on left operand type `User`
36 | _ = u
37 | u += 12
38 | u %= User{1, 3}
| ^
38 | u += User{2, 3}
39 | }
vlib/v/checker/tests/method_op_err.vv:38:7: error: operator `+` must return `User` to be used as an assignment operator
36 | u += 12
37 | u %= User{1, 3}
38 | u += User{2, 3}
39 | u += User{2, 3}
40 | }
vlib/v/checker/tests/method_op_err.vv:39:7: error: operator `+` must return `User` to be used as an assignment operator
37 | u += 12
38 | u %= User{1, 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, 4} < Foo{3, 4})
mut u := User{3, 4}
_ = u
u += 12
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
3 | p = 4
| ^
4 | _ = p

View File

@ -1,3 +1,4 @@
mut v := 43
mut p := &v
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 }
| ^
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`
4 | mut f := &Foo{ 10 }
5 | f = { x: 223344 }
6 | f = Foo{ x: 20 }
| ^
7 | }
7 | _ = f
8 | }

View File

@ -4,4 +4,5 @@ fn main() {
mut f := &Foo{ 10 }
f = { x: 223344 }
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 | }
8 |
vlib/v/checker/tests/sum.vv:10:7: error: cannot cast `rune` to `Var`
8 |
8 |
9 | fn sum() {
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('')
12 | s2 = true
| ~~~~
13 | }
13 | _ = s2
14 | }

View File

@ -10,4 +10,5 @@ fn sum() {
_ := Var(`J`)
mut s2 := Var('')
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{})
11 | w = IfExpr{}
| ~~~~~~~~
12 | }
12 | _ = w
13 | }

View File

@ -9,4 +9,5 @@ struct AnotherThing {}
fn main() {
mut w := Stmt(AnotherThing{})
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() {
2 | println(x)
| ^
3 | x := 'hello v'
4 | }
4 | _ = x

View File

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

View File

@ -5,4 +5,5 @@ fn main() {
a += x('a','b')
mut b := 'abcdef'
_ = 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
continue
}
obj.is_used = true
obj.is_used = true // TODO bug? sets all vars is_used to true
g.autofree_variable(obj)
// 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)' }
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
if p.peek_tok.kind == .dot && !known_var && (language != .v || p.known_import(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
| ^
16 | } else {1}
17 | }
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
24 | _ = opt() or {
25 | _ = 1
26 | &v
17 | _ = p
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
25 | _ = opt() or {
26 | _ = 1
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
11 |
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
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
22 | // later this should compile correctly
23 | v := 3
24 | _ = opt() or {
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
23 | // later this should compile correctly
24 | v := 3
25 | _ = opt() or {
| ~~~~
25 | _ = 1
26 | &v
26 | _ = 1
27 | &v

View File

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

View File

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

View File

@ -93,7 +93,7 @@ pub fn (mut p Preferences) fill_with_defaults() {
}
p.find_cc_if_cross_compiling()
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.is_vsh = p.path.ends_with('.vsh')
p.is_script = p.is_vsh || p.path.ends_with('.v') || p.path.ends_with('.vv')