| author | |
| committer | |
| log | 88284c124a0d930541f02ae9727118c0724f93f9 |
| tree | b55a7334f61f7c8a9516ee66e44aa4504d708d3a |
| parent | bbda053f9e309128ee4b2eb1a5b886aeb30fcabf |
Resolves: #162263 files changed, 62 insertions(+), 4 deletions(-)
src/AstGen.zig+21-4| ... | ... | @@ -1478,9 +1478,26 @@ fn arrayInitExpr( |
| 1478 | 1478 | |
| 1479 | 1479 | switch (ri.rl) { |
| 1480 | 1480 | .discard => { |
| 1481 | // TODO elements should still be coerced if type is provided | |
| 1482 | for (array_init.ast.elements) |elem_init| { | |
| 1483 | _ = try expr(gz, scope, .{ .rl = .discard }, elem_init); | |
| 1481 | if (types.elem != .none) { | |
| 1482 | const elem_ri: ResultInfo = .{ .rl = .{ .ty = types.elem } }; | |
| 1483 | for (array_init.ast.elements) |elem_init| { | |
| 1484 | _ = try expr(gz, scope, elem_ri, elem_init); | |
| 1485 | } | |
| 1486 | } else if (types.array != .none) { | |
| 1487 | for (array_init.ast.elements, 0..) |elem_init, i| { | |
| 1488 | const elem_ty = try gz.add(.{ | |
| 1489 | .tag = .elem_type_index, | |
| 1490 | .data = .{ .bin = .{ | |
| 1491 | .lhs = types.array, | |
| 1492 | .rhs = @enumFromInt(i), | |
| 1493 | } }, | |
| 1494 | }); | |
| 1495 | _ = try expr(gz, scope, .{ .rl = .{ .ty = elem_ty } }, elem_init); | |
| 1496 | } | |
| 1497 | } else { | |
| 1498 | for (array_init.ast.elements) |elem_init| { | |
| 1499 | _ = try expr(gz, scope, .{ .rl = .discard }, elem_init); | |
| 1500 | } | |
| 1484 | 1501 | } |
| 1485 | 1502 | return Zir.Inst.Ref.void_value; |
| 1486 | 1503 | }, |
| ... | ... | @@ -1569,7 +1586,7 @@ fn arrayInitExprInner( |
| 1569 | 1586 | for (elements, 0..) |elem_init, i| { |
| 1570 | 1587 | const ri = if (elem_ty != .none) |
| 1571 | 1588 | ResultInfo{ .rl = .{ .coerced_ty = elem_ty } } |
| 1572 | else if (array_ty_inst != .none and nodeMayNeedMemoryLocation(astgen.tree, elem_init, true)) ri: { | |
| 1589 | else if (array_ty_inst != .none) ri: { | |
| 1573 | 1590 | const ty_expr = try gz.add(.{ |
| 1574 | 1591 | .tag = .elem_type_index, |
| 1575 | 1592 | .data = .{ .bin = .{ |
test/behavior/array.zig+29| ... | ... | @@ -719,3 +719,32 @@ test "pointer to array has ptr field" { |
| 719 | 719 | try std.testing.expect(arr.ptr[3] == 40); |
| 720 | 720 | try std.testing.expect(arr.ptr[4] == 50); |
| 721 | 721 | } |
| 722 | ||
| 723 | test "discarded array init preserves result location" { | |
| 724 | const S = struct { | |
| 725 | fn f(p: *u32) u16 { | |
| 726 | p.* += 1; | |
| 727 | return 0; | |
| 728 | } | |
| 729 | }; | |
| 730 | ||
| 731 | var x: u32 = 0; | |
| 732 | _ = [2]u8{ | |
| 733 | @intCast(S.f(&x)), | |
| 734 | @intCast(S.f(&x)), | |
| 735 | }; | |
| 736 | ||
| 737 | // Ensure function was run | |
| 738 | try expect(x == 2); | |
| 739 | } | |
| 740 | ||
| 741 | test "array init with no result location has result type" { | |
| 742 | const x = .{ .foo = [2]u16{ | |
| 743 | @intCast(10), | |
| 744 | @intCast(20), | |
| 745 | } }; | |
| 746 | ||
| 747 | try expect(x.foo.len == 2); | |
| 748 | try expect(x.foo[0] == 10); | |
| 749 | try expect(x.foo[1] == 20); | |
| 750 | } |
test/cases/compile_errors/discarded_array_bad_elem_type.zig created+12| ... | ... | @@ -0,0 +1,12 @@ |
| 1 | export fn foo() void { | |
| 2 | _ = [2]u16{ | |
| 3 | "hello", | |
| 4 | "world", | |
| 5 | }; | |
| 6 | } | |
| 7 | ||
| 8 | // error | |
| 9 | // backend=llvm | |
| 10 | // target=native | |
| 11 | // | |
| 12 | // :3:9: error: expected type 'u16', found '*const [5:0]u8' |