mirror of
https://github.com/vlang/v.git
synced 2025-09-10 16:00:31 -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
|
if (right as ast.IndexExpr).left is ast.Ident
|
||||||
&& (right as ast.IndexExpr).index is ast.RangeExpr
|
&& (right as ast.IndexExpr).index is ast.RangeExpr
|
||||||
&& ((right as ast.IndexExpr).left.is_mut() || left.is_mut())
|
&& ((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() {
|
&& !got_type.is_ptr() {
|
||||||
c.error('allocate on the heap for use in other functions', init_field.pos)
|
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 exp_type_sym.kind == .interface_ {
|
||||||
if c.type_implements(got_type, exp_type, init_field.pos) {
|
if c.type_implements(got_type, exp_type, init_field.pos) {
|
||||||
if !c.inside_unsafe && got_type_sym.kind != .interface_
|
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