From 88284c124a0d930541f02ae9727118c0724f93f9 Mon Sep 17 00:00:00 2001 From: mlugg Date: Mon, 26 Jun 2023 20:41:42 +0100 Subject: [PATCH] AstGen: fix result locations for elements of typed array init Resolves: #16226 --- src/AstGen.zig | 25 +++++++++++++--- test/behavior/array.zig | 29 +++++++++++++++++++ .../discarded_array_bad_elem_type.zig | 12 ++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) create mode 100644 test/cases/compile_errors/discarded_array_bad_elem_type.zig diff --git a/src/AstGen.zig b/src/AstGen.zig index 27e8433cb6..ff7feef883 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -1478,9 +1478,26 @@ fn arrayInitExpr( switch (ri.rl) { .discard => { - // TODO elements should still be coerced if type is provided - for (array_init.ast.elements) |elem_init| { - _ = try expr(gz, scope, .{ .rl = .discard }, elem_init); + if (types.elem != .none) { + const elem_ri: ResultInfo = .{ .rl = .{ .ty = types.elem } }; + for (array_init.ast.elements) |elem_init| { + _ = try expr(gz, scope, elem_ri, elem_init); + } + } else if (types.array != .none) { + for (array_init.ast.elements, 0..) |elem_init, i| { + const elem_ty = try gz.add(.{ + .tag = .elem_type_index, + .data = .{ .bin = .{ + .lhs = types.array, + .rhs = @enumFromInt(i), + } }, + }); + _ = try expr(gz, scope, .{ .rl = .{ .ty = elem_ty } }, elem_init); + } + } else { + for (array_init.ast.elements) |elem_init| { + _ = try expr(gz, scope, .{ .rl = .discard }, elem_init); + } } return Zir.Inst.Ref.void_value; }, @@ -1569,7 +1586,7 @@ fn arrayInitExprInner( for (elements, 0..) |elem_init, i| { const ri = if (elem_ty != .none) ResultInfo{ .rl = .{ .coerced_ty = elem_ty } } - else if (array_ty_inst != .none and nodeMayNeedMemoryLocation(astgen.tree, elem_init, true)) ri: { + else if (array_ty_inst != .none) ri: { const ty_expr = try gz.add(.{ .tag = .elem_type_index, .data = .{ .bin = .{ diff --git a/test/behavior/array.zig b/test/behavior/array.zig index bc8176aa9c..82313cddc7 100644 --- a/test/behavior/array.zig +++ b/test/behavior/array.zig @@ -719,3 +719,32 @@ test "pointer to array has ptr field" { try std.testing.expect(arr.ptr[3] == 40); try std.testing.expect(arr.ptr[4] == 50); } + +test "discarded array init preserves result location" { + const S = struct { + fn f(p: *u32) u16 { + p.* += 1; + return 0; + } + }; + + var x: u32 = 0; + _ = [2]u8{ + @intCast(S.f(&x)), + @intCast(S.f(&x)), + }; + + // Ensure function was run + try expect(x == 2); +} + +test "array init with no result location has result type" { + const x = .{ .foo = [2]u16{ + @intCast(10), + @intCast(20), + } }; + + try expect(x.foo.len == 2); + try expect(x.foo[0] == 10); + try expect(x.foo[1] == 20); +} diff --git a/test/cases/compile_errors/discarded_array_bad_elem_type.zig b/test/cases/compile_errors/discarded_array_bad_elem_type.zig new file mode 100644 index 0000000000..edc64e40b0 --- /dev/null +++ b/test/cases/compile_errors/discarded_array_bad_elem_type.zig @@ -0,0 +1,12 @@ +export fn foo() void { + _ = [2]u16{ + "hello", + "world", + }; +} + +// error +// backend=llvm +// target=native +// +// :3:9: error: expected type 'u16', found '*const [5:0]u8'