checker: do not allow modifying consts via mutable refs
parent
b506d8fcc0
commit
7f5c3cc1f8
|
@ -586,3 +586,7 @@ fn test_truncate() {
|
||||||
assert newlen == os.file_size(filename)
|
assert newlen == os.file_size(filename)
|
||||||
os.rm(filename) or { panic(err) }
|
os.rm(filename) or { panic(err) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn test_hostname() {
|
||||||
|
assert os.hostname().len > 2
|
||||||
|
}
|
||||||
|
|
|
@ -3222,7 +3222,8 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
c.type_implements(right_type, left_type, right.position())
|
c.type_implements(right_type, left_type, right.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// this needs to run after the assign stmt left exprs have been run through checker so that ident.obj is set
|
// this needs to run after the assign stmt left exprs have been run through checker
|
||||||
|
// so that ident.obj is set
|
||||||
// Check `x := &y` and `mut x := <-ch`
|
// Check `x := &y` and `mut x := <-ch`
|
||||||
if right_first is ast.PrefixExpr {
|
if right_first is ast.PrefixExpr {
|
||||||
node := right_first
|
node := right_first
|
||||||
|
@ -3237,15 +3238,20 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
c.inside_ref_lit = (c.inside_ref_lit || node.op == .amp || is_shared)
|
c.inside_ref_lit = (c.inside_ref_lit || node.op == .amp || is_shared)
|
||||||
c.expr(node.right)
|
c.expr(node.right)
|
||||||
c.inside_ref_lit = old_inside_ref_lit
|
c.inside_ref_lit = old_inside_ref_lit
|
||||||
|
if node.op == .amp {
|
||||||
if node.right is ast.Ident {
|
if node.right is ast.Ident {
|
||||||
if node.right.obj is ast.Var {
|
if node.right.obj is ast.Var {
|
||||||
v := node.right.obj
|
v := node.right.obj
|
||||||
right_type0 = v.typ
|
right_type0 = v.typ
|
||||||
if node.op == .amp {
|
|
||||||
if !v.is_mut && assigned_var.is_mut && !c.inside_unsafe {
|
if !v.is_mut && assigned_var.is_mut && !c.inside_unsafe {
|
||||||
c.error('`$node.right.name` is immutable, cannot have a mutable reference to it',
|
c.error('`$node.right.name` is immutable, cannot have a mutable reference to it',
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
|
} else if node.right.obj is ast.ConstField {
|
||||||
|
if assigned_var.is_mut && !c.inside_unsafe {
|
||||||
|
c.error('`$node.right.name` is immutable, cannot have a mutable reference to it',
|
||||||
|
node.pos)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
g.v:9:6: warning: unused variable: `unused_var`
|
||||||
|
7 |
|
||||||
|
8 | fn main() {
|
||||||
|
9 | mut unused_var := Foo{}
|
||||||
|
| ~~~~~~~~~~
|
||||||
|
10 | unused_var = Foo{}
|
||||||
|
11 | mut c := &constant
|
||||||
|
g.v:11:14: error: `constant` is immutable, cannot have a mutable reference to it
|
||||||
|
9 | mut unused_var := Foo{}
|
||||||
|
10 | unused_var = Foo{}
|
||||||
|
11 | mut c := &constant
|
||||||
|
| ^
|
||||||
|
12 | c.value = 200
|
||||||
|
13 | }
|
|
@ -0,0 +1,13 @@
|
||||||
|
struct Foo {
|
||||||
|
mut:
|
||||||
|
value int
|
||||||
|
}
|
||||||
|
|
||||||
|
const constant = Foo{ 100 }
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
mut unused_var := Foo{}
|
||||||
|
unused_var = Foo{}
|
||||||
|
mut c := &constant
|
||||||
|
c.value = 200
|
||||||
|
}
|
Loading…
Reference in New Issue