checker: check variable mutability for postfix exprs

pull/4632/head
Enzo Baldisserri 2020-04-28 11:20:19 +02:00 committed by GitHub
parent 54b71242fe
commit 7bf8731778
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 120 additions and 18 deletions

View File

@ -136,7 +136,6 @@ pub fn bfand(input1 BitField, input2 BitField) BitField {
mut output := new(size)
for i in 0..bitnslots {
output.field[i] = input1.field[i] & input2.field[i]
i++
}
output.cleartail()
return output
@ -149,7 +148,6 @@ pub fn bfnot(input BitField) BitField {
mut output := new(size)
for i in 0..bitnslots {
output.field[i] = ~input.field[i]
i++
}
output.cleartail()
return output
@ -164,7 +162,6 @@ pub fn bfor(input1 BitField, input2 BitField) BitField {
mut output := new(size)
for i in 0..bitnslots {
output.field[i] = input1.field[i] | input2.field[i]
i++
}
output.cleartail()
return output
@ -179,7 +176,6 @@ pub fn bfxor(input1 BitField, input2 BitField) BitField {
mut output := new(size)
for i in 0..bitnslots {
output.field[i] = input1.field[i] ^ input2.field[i]
i++
}
output.cleartail()
return output
@ -241,7 +237,6 @@ pub fn (instance BitField) clone() BitField {
mut output := new(instance.size)
for i in 0..bitnslots {
output.field[i] = instance.field[i]
i++
}
return output
}

View File

@ -5,14 +5,14 @@ fn test_sb() {
sb.write('hi')
sb.write('!')
sb.write('hello')
assert sb.str() == 'hi!hello'
assert sb.len == 8
assert sb.str() == 'hi!hello'
assert sb.len == 0
sb = strings.new_builder(10)
sb.write('a')
sb.write('b')
println(sb.str())
assert sb.str() == 'ab'
assert sb.len == 2
assert sb.str() == 'ab'
}
const (

View File

@ -484,11 +484,11 @@ fn (mut c Checker) fail_if_immutable(expr ast.Expr) {
// TODO Remove `crypto.rand` when possible (see vlib/crypto/rand/rand.v,
// if `c_array_to_bytes_tmp` doesn't exist, then it's safe to remove it)
if c.file.mod.name !in ['builtin', 'crypto.rand'] {
c.error('`$typ_sym.kind` can not be modified', expr.position())
c.error('`$typ_sym.kind` can not be modified', it.pos)
}
}
else {
c.error('unexpected symbol `${typ_sym.kind}`', expr.position())
c.error('unexpected symbol `${typ_sym.kind}`', it.pos)
}
}
}
@ -1802,20 +1802,14 @@ pub fn (mut c Checker) if_expr(node mut ast.IfExpr) table.Type {
}
pub fn (mut c Checker) postfix_expr(node ast.PostfixExpr) table.Type {
/*
match node.expr {
ast.IdentVar {
println('postfix identvar')
}
else {}
}
*/
typ := c.expr(node.expr)
typ_sym := c.table.get_type_symbol(typ)
// if !typ.is_number() {
if !typ_sym.is_number() {
println(typ_sym.kind.str())
c.error('invalid operation: $node.op.str() (non-numeric type `$typ_sym.name`)', node.pos)
} else {
c.fail_if_immutable(node.expr)
}
return typ
}

View File

@ -0,0 +1,3 @@
fn main() {
println(1/0)
}

View File

@ -0,0 +1,13 @@
vlib/v/checker/tests/immutable_field_postfix.v:7:4: error: field `i` of struct `A` is immutable
5| fn main() {
6| mut a := A{}
7| a.i++
^
8| a.i--
9| }
vlib/v/checker/tests/immutable_field_postfix.v:8:4: error: field `i` of struct `A` is immutable
6| mut a := A{}
7| a.i++
8| a.i--
^
9| }

View File

@ -0,0 +1,9 @@
struct A {
i int
}
fn main() {
mut a := A{}
a.i++
a.i--
}

View File

@ -0,0 +1,9 @@
struct A {
i int
}
fn main() {
mut a := A{}
a.i++
a.i--
}

View File

@ -0,0 +1,13 @@
vlib/v/checker/tests/immutable_map_postfix.v:3:2: error: `m` is immutable, declare it with `mut` to make it mutable
1| fn main() {
2| m := map[string]int
3| m['test']++
^
4| m['test']--
5| }
vlib/v/checker/tests/immutable_map_postfix.v:4:2: error: `m` is immutable, declare it with `mut` to make it mutable
2| m := map[string]int
3| m['test']++
4| m['test']--
^
5| }

View File

@ -0,0 +1,5 @@
fn main() {
m := map[string]int
m['test']++
m['test']--
}

View File

@ -0,0 +1,5 @@
fn main() {
m := map[string]int
m['test']++
m['test']--
}

View File

@ -0,0 +1,13 @@
vlib/v/checker/tests/immutable_struct_postfix.v:8:2: error: `a` is immutable, declare it with `mut` to make it mutable
6| fn main() {
7| a := A{}
8| a.i++
^
9| a.i--
10| }
vlib/v/checker/tests/immutable_struct_postfix.v:9:2: error: `a` is immutable, declare it with `mut` to make it mutable
7| a := A{}
8| a.i++
9| a.i--
^
10| }

View File

@ -0,0 +1,10 @@
struct A {
mut:
i int
}
fn main() {
a := A{}
a.i++
a.i--
}

View File

@ -0,0 +1,10 @@
struct A {
mut:
i int
}
fn main() {
a := A{}
a.i++
a.i--
}

View File

@ -0,0 +1,13 @@
vlib/v/checker/tests/immutable_var_postfix.v:3:2: error: `a` is immutable, declare it with `mut` to make it mutable
1| fn main() {
2| a := 1
3| a++
^
4| a--
5| }
vlib/v/checker/tests/immutable_var_postfix.v:4:2: error: `a` is immutable, declare it with `mut` to make it mutable
2| a := 1
3| a++
4| a--
^
5| }

View File

@ -0,0 +1,5 @@
fn main() {
a := 1
a++
a--
}

View File

@ -0,0 +1,5 @@
fn main() {
a := 1
a++
a--
}