authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2023-06-26 20:41:42+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-26 16:20:33-07:00
log88284c124a0d930541f02ae9727118c0724f93f9
treeb55a7334f61f7c8a9516ee66e44aa4504d708d3a
parentbbda053f9e309128ee4b2eb1a5b886aeb30fcabf

AstGen: fix result locations for elements of typed array init

Resolves: #16226

3 files changed, 62 insertions(+), 4 deletions(-)

src/AstGen.zig+21-4
......@@ -1478,9 +1478,26 @@ fn arrayInitExpr(
14781478
14791479 switch (ri.rl) {
14801480 .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 }
14841501 }
14851502 return Zir.Inst.Ref.void_value;
14861503 },
......@@ -1569,7 +1586,7 @@ fn arrayInitExprInner(
15691586 for (elements, 0..) |elem_init, i| {
15701587 const ri = if (elem_ty != .none)
15711588 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: {
15731590 const ty_expr = try gz.add(.{
15741591 .tag = .elem_type_index,
15751592 .data = .{ .bin = .{
test/behavior/array.zig+29
......@@ -719,3 +719,32 @@ test "pointer to array has ptr field" {
719719 try std.testing.expect(arr.ptr[3] == 40);
720720 try std.testing.expect(arr.ptr[4] == 50);
721721}
722
723test "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
741test "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 @@
1export 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'