checker: fix for _, mut j in array (#8785)
parent
600f6ad2a0
commit
4fa315edc2
|
@ -1537,12 +1537,20 @@ pub struct Table {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (expr Expr) is_mut_ident() bool {
|
pub fn (expr Expr) is_mut_ident() bool {
|
||||||
if expr is Ident {
|
match expr {
|
||||||
if expr.obj is Var {
|
Ident {
|
||||||
if expr.obj.is_auto_deref {
|
if expr.obj is Var {
|
||||||
|
if expr.obj.is_auto_deref {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PrefixExpr {
|
||||||
|
if expr.op == .amp && expr.right.is_mut_ident() {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1406,7 +1406,11 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
// need to return `array_xxx` instead of `array`
|
// need to return `array_xxx` instead of `array`
|
||||||
// in ['clone', 'str'] {
|
// in ['clone', 'str'] {
|
||||||
call_expr.receiver_type = left_type.to_ptr()
|
call_expr.receiver_type = left_type.to_ptr()
|
||||||
call_expr.return_type = call_expr.receiver_type.set_nr_muls(0)
|
if call_expr.left.is_mut_ident() {
|
||||||
|
call_expr.return_type = left_type.deref()
|
||||||
|
} else {
|
||||||
|
call_expr.return_type = call_expr.receiver_type.set_nr_muls(0)
|
||||||
|
}
|
||||||
} else if method_name == 'sort' {
|
} else if method_name == 'sort' {
|
||||||
call_expr.return_type = table.void_type
|
call_expr.return_type = table.void_type
|
||||||
} else if method_name == 'contains' {
|
} else if method_name == 'contains' {
|
||||||
|
@ -1422,7 +1426,11 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
||||||
if method_name[0] == `m` {
|
if method_name[0] == `m` {
|
||||||
c.fail_if_immutable(call_expr.left)
|
c.fail_if_immutable(call_expr.left)
|
||||||
}
|
}
|
||||||
ret_type = left_type
|
if call_expr.left.is_mut_ident() {
|
||||||
|
ret_type = left_type.deref()
|
||||||
|
} else {
|
||||||
|
ret_type = left_type
|
||||||
|
}
|
||||||
}
|
}
|
||||||
'keys' {
|
'keys' {
|
||||||
info := left_type_sym.info as table.Map
|
info := left_type_sym.info as table.Map
|
||||||
|
@ -2849,7 +2857,8 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !is_blank_ident && right_sym.kind != .placeholder && left_sym.kind != .interface_ {
|
if !is_blank_ident && !right.is_mut_ident() && right_sym.kind != .placeholder
|
||||||
|
&& left_sym.kind != .interface_ {
|
||||||
// Dual sides check (compatibility check)
|
// Dual sides check (compatibility check)
|
||||||
c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
|
c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
|
||||||
c.error('cannot assign to `$left`: $err', right.position())
|
c.error('cannot assign to `$left`: $err', right.position())
|
||||||
|
|
|
@ -254,3 +254,97 @@ fn test_mut_12() {
|
||||||
mut arr := [[0, 0]]
|
mut arr := [[0, 0]]
|
||||||
foo3(mut arr)
|
foo3(mut arr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct Foo {
|
||||||
|
mut:
|
||||||
|
foo int
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo4(mut f Foo) {
|
||||||
|
f2 := &f
|
||||||
|
f.foo = 100
|
||||||
|
println(f.foo)
|
||||||
|
println(f2.foo)
|
||||||
|
assert f.foo == 100
|
||||||
|
assert f2.foo == 100
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_mut_13() {
|
||||||
|
mut f := Foo{foo: 1}
|
||||||
|
foo4(mut f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo5(mut arr []int) {
|
||||||
|
arr2 := &arr
|
||||||
|
arr[0] = 0
|
||||||
|
println(arr[0]) // 0
|
||||||
|
assert arr[0] == 0
|
||||||
|
unsafe {
|
||||||
|
println(arr2[0]) // 0
|
||||||
|
assert arr2[0] == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_mut_14() {
|
||||||
|
mut arr := [1,2,3]
|
||||||
|
foo5(mut arr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo6(mut arr [3]int) {
|
||||||
|
arr2 := &arr
|
||||||
|
arr[0] = 0
|
||||||
|
println(arr[0]) // 0
|
||||||
|
assert arr[0] == 0
|
||||||
|
unsafe {
|
||||||
|
println(arr2[0]) // 0
|
||||||
|
assert arr2[0] == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_mut_15() {
|
||||||
|
mut arr := [1,2,3]!
|
||||||
|
foo6(mut arr)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo7(mut m map[string]int) {
|
||||||
|
m2 := &m
|
||||||
|
m['one'] = 1
|
||||||
|
println(m['one']) // 1
|
||||||
|
assert m['one'] == 1
|
||||||
|
unsafe {
|
||||||
|
println(m2['one']) // 1
|
||||||
|
assert m2['one'] == 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_mut_16() {
|
||||||
|
mut m := map{'one': 100, 'two': 2}
|
||||||
|
foo7(mut m)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_mut_17() {
|
||||||
|
mut arr := [map{'foo':1}]
|
||||||
|
for _, mut j in arr {
|
||||||
|
mut k := j.clone()
|
||||||
|
j['foo'] = 0
|
||||||
|
unsafe {k['foo'] = 10}
|
||||||
|
println(j)
|
||||||
|
println(k)
|
||||||
|
assert j == {'foo': 0}
|
||||||
|
assert k == {'foo': 10}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo8(mut a [1]int) {
|
||||||
|
a2 := a
|
||||||
|
a[0] = 100
|
||||||
|
println(a)
|
||||||
|
println(a2)
|
||||||
|
assert '$a' == '[100]'
|
||||||
|
assert '$a2' == '[1]'
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_mut_18() {
|
||||||
|
mut a := [1]!
|
||||||
|
foo8(mut a)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue