@@ -1239,6 +1239,12 @@ fn (mut c Checker) infix_expr(expr ast.InfixExpr) Type {
12391239 expected_type := c.expected_type
12401240 c.set_infix_expected_type (expr, lhs_type)
12411241 rhs_type := c.infix_rhs_type (expr)
1242+ $if ownership ? {
1243+ lhs_base := lhs_type.base_type ()
1244+ if expr.op == .left_shift && (lhs_type is Array || lhs_base is Array ) {
1245+ c.ownership_consume_expr (expr.rhs, expr.rhs.pos (), "array append" )
1246+ }
1247+ }
12421248 c.expected_type = expected_type
12431249 if expr.op.is_comparison () {
12441250 return bool_
@@ -1290,13 +1296,19 @@ fn (mut c Checker) init_expr(expr ast.InitExpr) Type {
12901296 }
12911297 }
12921298 c.expr (field.value)
1299+ $if ownership ? {
1300+ c.ownership_consume_expr (field.value, field.value.pos (), "struct field" )
1301+ }
12931302 c.expected_type = expected_type_prev
12941303 }
12951304 }
12961305 } else {
12971306 for field in expr.fields {
12981307 if field.value ! is ast.EmptyExpr {
12991308 c.expr (field.value)
1309+ $if ownership ? {
1310+ c.ownership_consume_expr (field.value, field.value.pos (), "struct field" )
1311+ }
13001312 }
13011313 }
13021314 }
@@ -1371,6 +1383,10 @@ fn (mut c Checker) map_init_expr(expr ast.MapInitExpr) Type {
13711383 if ! has_map_type {
13721384 map_key_type = c.expr (expr.keys[0 ]).typed_default ()
13731385 map_value_type = c.expr (expr.vals[0 ]).typed_default ()
1386+ $if ownership ? {
1387+ c.ownership_consume_expr (expr.keys[0 ], expr.keys[0 ].pos (), "map key" )
1388+ c.ownership_consume_expr (expr.vals[0 ], expr.vals[0 ].pos (), "map value" )
1389+ }
13741390 has_map_type = true
13751391 inferred_from_first_entry = true
13761392 }
@@ -1384,6 +1400,10 @@ fn (mut c Checker) map_init_expr(expr ast.MapInitExpr) Type {
13841400 key_type := c.expr (key_expr).typed_default ()
13851401 c.expected_type = to_optional_type (map_value_type)
13861402 val_type := c.expr (val_expr).typed_default ()
1403+ $if ownership ? {
1404+ c.ownership_consume_expr (key_expr, key_expr.pos (), "map key" )
1405+ c.ownership_consume_expr (val_expr, val_expr.pos (), "map value" )
1406+ }
13871407 if ! c.check_types (map_key_type, key_type) {
13881408 c.error_with_pos ('invalid map key: expecting ${map_key_type .name ()}, got ${key_type .name ()}' ,
13891409 key_expr.pos ())
@@ -1519,6 +1539,9 @@ fn (mut c Checker) expr_impl(expr ast.Expr) Type {
15191539 is_fixed := ! is_empty_expr (expr.len)
15201540 // TODO: check all exprs
15211541 first_elem_type := c.expr (expr.exprs.first ())
1542+ $if ownership ? {
1543+ c.ownership_consume_expr (expr.exprs.first (), expr.exprs.first ().pos (), "array element" )
1544+ }
15221545 // NOTE: why did I have this shortcut here?
15231546 // if expr.exprs.len == 1 {
15241547 // if first_elem_type.is_number_literal() {
@@ -1545,6 +1568,9 @@ fn (mut c Checker) expr_impl(expr ast.Expr) Type {
15451568 continue
15461569 }
15471570 mut elem_type := c.expr (elem_expr)
1571+ $if ownership ? {
1572+ c.ownership_consume_expr (elem_expr, elem_expr.pos (), "array element" )
1573+ }
15481574 // TODO: best way to handle this?
15491575 if elem_type.is_number_literal () && first_elem_type.is_number () {
15501576 elem_type = first_elem_type
@@ -2614,6 +2640,9 @@ fn (mut c Checker) check_struct_field_defaults(files []ast.File) {
26142640 prev_expected := c.expected_type
26152641 c.expected_type = to_optional_type (field_typ)
26162642 c.expr (field.value)
2643+ $if ownership ? {
2644+ c.ownership_consume_expr (field.value, field.value.pos (), "struct field" )
2645+ }
26172646 c.expected_type = prev_expected
26182647 }
26192648 }
@@ -2814,6 +2843,11 @@ fn (mut c Checker) assign_stmt(stmt ast.AssignStmt, unwrap_optional bool) {
28142843 c.ownership_check_reassign (lhs_name, stmt.pos)
28152844 // Also check if new value is owned (via .to_owned() or fn return)
28162845 c.ownership_mark_from_call (lhs_name, rx, stmt.pos)
2846+ } else if stmt.op in [.left_shift, .left_shift_assign] {
2847+ lhs_base := lhs_type.base_type ()
2848+ if lhs_type is Array || lhs_base is Array {
2849+ c.ownership_consume_expr (rx, rx.pos (), "array append" )
2850+ }
28172851 }
28182852 }
28192853 }
0 commit comments