checker: check for mut val in immutable obj (#8285)

pull/8292/head
yuyi 2021-01-23 17:40:17 +08:00 committed by GitHub
parent d4f6f5eec4
commit 5ee3fecf60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 115 additions and 34 deletions

View File

@ -4,17 +4,38 @@ import os
import term
import time
const vexe = os.getenv('VEXE')
const vroot = os.dir(vexe)
const args_string = os.args[1..].join(' ')
const vargs = args_string.all_before('test-all')
const (
vexe = os.getenv('VEXE')
vroot = os.dir(vexe)
args_string = os.args[1..].join(' ')
vargs = args_string.all_before('test-all')
)
fn main() {
commands := get_all_commands()
commands.summary()
mut commands := get_all_commands()
// summary
sw := time.new_stopwatch({})
for mut cmd in commands {
cmd.run()
}
spent := sw.elapsed().milliseconds()
oks := commands.filter(it.ecode == 0)
fails := commands.filter(it.ecode != 0)
println('')
println(term.header(term.colorize(term.yellow, term.colorize(term.bold, 'Summary of `v test-all`:')),
'-'))
println(term.colorize(term.yellow, 'Total runtime: $spent ms'))
for ocmd in oks {
msg := if ocmd.okmsg != '' { ocmd.okmsg } else { ocmd.line }
println(term.colorize(term.green, '> OK: $msg '))
}
for fcmd in fails {
msg := if fcmd.errmsg != '' { fcmd.errmsg } else { fcmd.line }
println(term.colorize(term.red, '> Failed: $msg '))
}
if fails.len > 0 {
exit(1)
}
}
struct Command {
@ -80,28 +101,3 @@ fn (mut cmd Command) run() {
println(term.colorize(term.yellow, '> Running: "$cmd.line" took: $spent ms.'))
println('')
}
fn (commands []Command) summary() {
sw := time.new_stopwatch({})
for mut cmd in commands {
cmd.run()
}
spent := sw.elapsed().milliseconds()
oks := commands.filter(it.ecode == 0)
fails := commands.filter(it.ecode != 0)
println('')
println(term.header(term.colorize(term.yellow, term.colorize(term.bold, 'Summary of `v test-all`:')),
'-'))
println(term.colorize(term.yellow, 'Total runtime: $spent ms'))
for ocmd in oks {
msg := if ocmd.okmsg != '' { ocmd.okmsg } else { ocmd.line }
println(term.colorize(term.green, '> OK: $msg '))
}
for fcmd in fails {
msg := if fcmd.errmsg != '' { fcmd.errmsg } else { fcmd.line }
println(term.colorize(term.red, '> Failed: $msg '))
}
if fails.len > 0 {
exit(1)
}
}

View File

@ -3079,6 +3079,26 @@ fn (mut c Checker) stmt(node ast.Stmt) {
}
if node.val_is_mut {
value_type = value_type.to_ptr()
match node.cond {
ast.Ident {
if node.cond.obj is ast.Var {
obj := node.cond.obj as ast.Var
if !obj.is_mut {
c.error('`$obj.name` is immutable, it cannot be changed',
node.cond.pos)
}
}
}
ast.ArrayInit {
c.error('array literal is immutable, it cannot be changed',
node.cond.pos)
}
ast.MapInit {
c.error('map literal is immutable, it cannot be changed',
node.cond.pos)
}
else {}
}
}
node.cond_type = typ
node.kind = sym.kind

View File

@ -0,0 +1,42 @@
vlib/v/checker/tests/for_in_mut_val_type.vv:3:15: error: `a1` is immutable, it cannot be changed
1 | fn main() {
2 | a1 := [1, 2, 3]
3 | for mut j in a1 {
| ~~
4 | j *= 2
5 | }
vlib/v/checker/tests/for_in_mut_val_type.vv:7:15: error: `a2` is immutable, it cannot be changed
5 | }
6 | a2 := [1, 2, 3]!
7 | for mut j in a2 {
| ~~
8 | j *= 2
9 | }
vlib/v/checker/tests/for_in_mut_val_type.vv:11:18: error: `m` is immutable, it cannot be changed
9 | }
10 | m := {'aa': 1, 'bb': 2}
11 | for _, mut j in m {
| ^
12 | j *= 2
13 | }
vlib/v/checker/tests/for_in_mut_val_type.vv:14:15: error: array literal is immutable, it cannot be changed
12 | j *= 2
13 | }
14 | for mut j in [1, 2, 3] {
| ~~~~~~~~~
15 | j *= 2
16 | }
vlib/v/checker/tests/for_in_mut_val_type.vv:17:15: error: array literal is immutable, it cannot be changed
15 | j *= 2
16 | }
17 | for mut j in [1, 2, 3]! {
| ~~~~~~~~~~
18 | j *= 2
19 | }
vlib/v/checker/tests/for_in_mut_val_type.vv:20:19: error: map literal is immutable, it cannot be changed
18 | j *= 2
19 | }
20 | for _, mut j in {'aa': 1, 'bb': 2} {
| ~~~~
21 | j *= 2
22 | }

View File

@ -0,0 +1,23 @@
fn main() {
a1 := [1, 2, 3]
for mut j in a1 {
j *= 2
}
a2 := [1, 2, 3]!
for mut j in a2 {
j *= 2
}
m := {'aa': 1, 'bb': 2}
for _, mut j in m {
j *= 2
}
for mut j in [1, 2, 3] {
j *= 2
}
for mut j in [1, 2, 3]! {
j *= 2
}
for _, mut j in {'aa': 1, 'bb': 2} {
j *= 2
}
}