checker: fix assigning array slice in struct init (#19150)

This commit is contained in:
yuyi 2023-08-16 18:33:58 +08:00 committed by GitHub
parent 06e2bc5df2
commit d0e605750b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 53 additions and 1 deletions

View File

@ -483,7 +483,8 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
}
}
}
} else if mut left is ast.Ident && right is ast.IndexExpr {
} else if mut left is ast.Ident && left.kind != .blank_ident
&& right is ast.IndexExpr {
if (right as ast.IndexExpr).left is ast.Ident
&& (right as ast.IndexExpr).index is ast.RangeExpr
&& ((right as ast.IndexExpr).left.is_mut() || left.is_mut())

View File

@ -566,6 +566,30 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
&& !got_type.is_ptr() {
c.error('allocate on the heap for use in other functions', init_field.pos)
}
if exp_type_sym.kind == .array && got_type_sym.kind == .array {
if init_field.expr is ast.IndexExpr
&& (init_field.expr as ast.IndexExpr).left is ast.Ident
&& ((init_field.expr as ast.IndexExpr).left.is_mut()
|| field_info.is_mut) && init_field.expr.index is ast.RangeExpr
&& !c.inside_unsafe {
// `a: arr[..]` auto add clone() -> `a: arr[..].clone()`
c.add_error_detail_with_pos('To silence this notice, use either an explicit `a[..].clone()`,
or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.',
init_field.expr.pos())
c.note('an implicit clone of the slice was done here', init_field.expr.pos())
mut right := ast.CallExpr{
name: 'clone'
left: init_field.expr
left_type: got_type
is_method: true
receiver_type: got_type.ref()
return_type: got_type
scope: c.fn_scope
}
got_type = c.expr(mut right)
node.init_fields[i].expr = right
}
}
if exp_type_sym.kind == .interface_ {
if c.type_implements(got_type, exp_type, init_field.pos) {
if !c.inside_unsafe && got_type_sym.kind != .interface_

View File

@ -0,0 +1,15 @@
vlib/v/checker/tests/slice_clone_in_struct_init_notice.vv:9:7: notice: an implicit clone of the slice was done here
7 |
8 | _ := AA{
9 | a: a[0..5]
| ~~~~~~
10 | }
11 | _ := a[0..5]
Details: vlib/v/checker/tests/slice_clone_in_struct_init_notice.vv:9:7: details: To silence this notice, use either an explicit `a[..].clone()`,
or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.
7 |
8 | _ := AA{
9 | a: a[0..5]
| ~~~~~~
10 | }
11 | _ := a[0..5]

View File

@ -0,0 +1,12 @@
struct AA {
a []int
}
fn main() {
mut a := []int{len: 10}
_ := AA{
a: a[0..5]
}
_ := a[0..5]
}