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)
|
||||
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())
|
||||
}
|
||||
}
|
||||
// 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`
|
||||
if right_first is ast.PrefixExpr {
|
||||
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.expr(node.right)
|
||||
c.inside_ref_lit = old_inside_ref_lit
|
||||
if node.right is ast.Ident {
|
||||
if node.right.obj is ast.Var {
|
||||
v := node.right.obj
|
||||
right_type0 = v.typ
|
||||
if node.op == .amp {
|
||||
if node.op == .amp {
|
||||
if node.right is ast.Ident {
|
||||
if node.right.obj is ast.Var {
|
||||
v := node.right.obj
|
||||
right_type0 = v.typ
|
||||
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',
|
||||
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