checker: check array builtin method calls, that do need a mutable receiver, but are called on an immutable one (fix #22850) (#22853)

This commit is contained in:
yuyi 2024-11-14 19:24:34 +08:00 committed by GitHub
parent 58e5799ac2
commit 409f6fb642
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 92 additions and 14 deletions

View File

@ -3301,6 +3301,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
return ast.void_type
}
}
c.check_for_mut_receiver(mut node.left)
info := left_sym.info as ast.Array
mut arg_expr := if method_name == 'insert' {
node.args[1].expr
@ -3362,6 +3363,7 @@ fn (mut c Checker) array_builtin_method_call(mut node ast.CallExpr, left_type as
}
}
if method_name == 'sort_with_compare' {
c.check_for_mut_receiver(mut node.left)
node.return_type = ast.void_type
node.receiver_type = node.left_type.ref()
} else {
@ -3773,6 +3775,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t
c.check_expr_option_or_result_call(arg.expr, c.expr(mut arg.expr))
}
if method_name == 'sort_with_compare' {
c.check_for_mut_receiver(mut node.left)
node.return_type = ast.void_type
node.receiver_type = node.left_type.ref()
} else {
@ -3787,6 +3790,7 @@ fn (mut c Checker) fixed_array_builtin_method_call(mut node ast.CallExpr, left_t
if method_name == 'reverse' {
node.return_type = node.left_type
} else {
c.check_for_mut_receiver(mut node.left)
node.return_type = ast.void_type
}
}

View File

@ -0,0 +1,55 @@
vlib/v/checker/tests/array_method_call_immutable_err.vv:7:2: error: `a2` is immutable, declare it with `mut` to make it mutable
5 | a3 := ['aa', 'bb']
6 |
7 | a2.prepend(a1)
| ~~
8 | a1.insert(0, a0)
9 | a3.sort_with_compare(fn (a &string, b &string) int {
vlib/v/checker/tests/array_method_call_immutable_err.vv:8:2: error: `a1` is immutable, declare it with `mut` to make it mutable
6 |
7 | a2.prepend(a1)
8 | a1.insert(0, a0)
| ~~
9 | a3.sort_with_compare(fn (a &string, b &string) int {
10 | if a < b {
vlib/v/checker/tests/array_method_call_immutable_err.vv:9:2: error: `a3` is immutable, declare it with `mut` to make it mutable
7 | a2.prepend(a1)
8 | a1.insert(0, a0)
9 | a3.sort_with_compare(fn (a &string, b &string) int {
| ~~
10 | if a < b {
11 | return -1
vlib/v/checker/tests/array_method_call_immutable_err.vv:18:2: error: `a3` is immutable, declare it with `mut` to make it mutable
16 | return 0
17 | })
18 | a3.delete(0)
| ~~
19 | a2.pop()
20 | a3.sort()
vlib/v/checker/tests/array_method_call_immutable_err.vv:19:2: error: `a2` is immutable, declare it with `mut` to make it mutable
17 | })
18 | a3.delete(0)
19 | a2.pop()
| ~~
20 | a3.sort()
21 |
vlib/v/checker/tests/array_method_call_immutable_err.vv:20:2: error: `a3` is immutable, declare it with `mut` to make it mutable
18 | a3.delete(0)
19 | a2.pop()
20 | a3.sort()
| ~~
21 |
22 | b0 := ['aa', 'bb']!
vlib/v/checker/tests/array_method_call_immutable_err.vv:23:2: error: `b0` is immutable, declare it with `mut` to make it mutable
21 |
22 | b0 := ['aa', 'bb']!
23 | b0.sort_with_compare(fn (a &string, b &string) int {
| ~~
24 | if a < b {
25 | return -1
vlib/v/checker/tests/array_method_call_immutable_err.vv:32:2: error: `b0` is immutable, declare it with `mut` to make it mutable
30 | return 0
31 | })
32 | b0.sort()
| ~~
33 | }

View File

@ -0,0 +1,33 @@
fn main() {
a0 := [1, 2]
a1 := [3, 4]
a2 := [5, 6]
a3 := ['aa', 'bb']
a2.prepend(a1)
a1.insert(0, a0)
a3.sort_with_compare(fn (a &string, b &string) int {
if a < b {
return -1
}
if a > b {
return 1
}
return 0
})
a3.delete(0)
a2.pop()
a3.sort()
b0 := ['aa', 'bb']!
b0.sort_with_compare(fn (a &string, b &string) int {
if a < b {
return -1
}
if a > b {
return 1
}
return 0
})
b0.sort()
}

View File

@ -1,7 +0,0 @@
vlib/v/checker/tests/array_pop_immutable_err.vv:5:2: error: `a` is immutable, declare it with `mut` to make it mutable
3 | dump(a)
4 |
5 | a.pop()
| ^
6 | dump(a)
7 | }

View File

@ -1,7 +0,0 @@
fn main() {
a := [1, 2, 3]
dump(a)
a.pop()
dump(a)
}