mirror of
https://github.com/vlang/v.git
synced 2025-09-10 07:47:20 -04:00
checker: fix assigning array slice in struct init (#19150)
This commit is contained in:
parent
06e2bc5df2
commit
d0e605750b
@ -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())
|
||||
|
@ -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_
|
||||
|
15
vlib/v/checker/tests/slice_clone_in_struct_init_notice.out
Normal file
15
vlib/v/checker/tests/slice_clone_in_struct_init_notice.out
Normal 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]
|
12
vlib/v/checker/tests/slice_clone_in_struct_init_notice.vv
Normal file
12
vlib/v/checker/tests/slice_clone_in_struct_init_notice.vv
Normal file
@ -0,0 +1,12 @@
|
||||
struct AA {
|
||||
a []int
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mut a := []int{len: 10}
|
||||
|
||||
_ := AA{
|
||||
a: a[0..5]
|
||||
}
|
||||
_ := a[0..5]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user