checker: disallow `mut_ptr = &immutable_var`
Previously only initialization was detected. Also add fn Ident.is_mut().pull/13814/head
parent
9bbb52e9cc
commit
5ed1f52e59
|
|
@ -794,7 +794,21 @@ pub mut:
|
|||
name string
|
||||
kind IdentKind
|
||||
info IdentInfo
|
||||
is_mut bool
|
||||
is_mut bool // if mut *token* is before name. Use `is_mut()` to lookup mut variable
|
||||
}
|
||||
|
||||
pub fn (i &Ident) is_mut() bool {
|
||||
match i.obj {
|
||||
Var {
|
||||
return i.obj.is_mut
|
||||
}
|
||||
ConstField {
|
||||
return false
|
||||
}
|
||||
AsmRegister, GlobalField {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (i &Ident) var_info() IdentVar {
|
||||
|
|
|
|||
|
|
@ -559,15 +559,10 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
|
|||
if right_node.right.obj is ast.Var {
|
||||
v := right_node.right.obj
|
||||
right_type0 = v.typ
|
||||
if !v.is_mut && assigned_var.is_mut && !c.inside_unsafe {
|
||||
c.error('`$right_node.right.name` is immutable, cannot have a mutable reference to it',
|
||||
right_node.pos)
|
||||
}
|
||||
} else if right_node.right.obj is ast.ConstField {
|
||||
if assigned_var.is_mut && !c.inside_unsafe {
|
||||
c.error('`$right_node.right.name` is immutable, cannot have a mutable reference to it',
|
||||
right_node.pos)
|
||||
}
|
||||
}
|
||||
if !c.inside_unsafe && assigned_var.is_mut() && !right_node.right.is_mut() {
|
||||
c.error('`$right_node.right.name` is immutable, cannot have a mutable reference to it',
|
||||
right_node.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
vlib/v/checker/tests/modify_const_with_ref.vv:11:11: 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 | }
|
||||
vlib/v/checker/tests/modify_const_with_ref.vv:9:6: error: unused variable: `unused_var`
|
||||
7 |
|
||||
8 | fn main() {
|
||||
9 | mut unused_var := Foo{}
|
||||
| ~~~~~~~~~~
|
||||
10 | unused_var = Foo{}
|
||||
11 | mut c := &constant
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
struct Foo {
|
||||
mut:
|
||||
value int
|
||||
}
|
||||
|
||||
const constant = Foo{ 100 }
|
||||
|
||||
fn main() {
|
||||
mut unused_var := Foo{}
|
||||
unused_var = Foo{}
|
||||
mut c := &constant
|
||||
c.value = 200
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
vlib/v/checker/tests/mut_assign_ref.vv:10:12: error: `f` is immutable, cannot have a mutable reference to it
|
||||
8 | fn main() {
|
||||
9 | f := Foo{}
|
||||
10 | mut pf := &f
|
||||
| ^
|
||||
11 | pf = &f
|
||||
12 | p := &f
|
||||
vlib/v/checker/tests/mut_assign_ref.vv:11:7: error: `f` is immutable, cannot have a mutable reference to it
|
||||
9 | f := Foo{}
|
||||
10 | mut pf := &f
|
||||
11 | pf = &f
|
||||
| ^
|
||||
12 | p := &f
|
||||
13 | _ = p
|
||||
vlib/v/checker/tests/mut_assign_ref.vv:15:11: error: `constant` is immutable, cannot have a mutable reference to it
|
||||
13 | _ = p
|
||||
14 |
|
||||
15 | mut c := &constant
|
||||
| ^
|
||||
16 | c.value = 200
|
||||
17 | c = &constant
|
||||
vlib/v/checker/tests/mut_assign_ref.vv:17:6: error: `constant` is immutable, cannot have a mutable reference to it
|
||||
15 | mut c := &constant
|
||||
16 | c.value = 200
|
||||
17 | c = &constant
|
||||
| ^
|
||||
18 | ic := &constant // ok
|
||||
19 | _=ic
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
struct Foo {
|
||||
mut:
|
||||
value int
|
||||
}
|
||||
|
||||
const constant = Foo{ 100 }
|
||||
|
||||
fn main() {
|
||||
f := Foo{}
|
||||
mut pf := &f
|
||||
pf = &f
|
||||
p := &f
|
||||
_ = p
|
||||
|
||||
mut c := &constant
|
||||
c.value = 200
|
||||
c = &constant
|
||||
ic := &constant // ok
|
||||
_=ic
|
||||
|
||||
mut mf := f
|
||||
pf = &mf // ok
|
||||
_ = pf
|
||||
}
|
||||
Loading…
Reference in New Issue