frontend: forbid packed and extern tuples

This commit is contained in:
Andrew Kelley 2023-07-25 10:46:49 -07:00
parent 4b7fa0fce9
commit 6cee98eb30
5 changed files with 17 additions and 25 deletions

View File

@ -4687,6 +4687,13 @@ fn structDeclInner(
const container_field = tree.fullContainerField(member_node) orelse continue; const container_field = tree.fullContainerField(member_node) orelse continue;
if (container_field.ast.tuple_like) break true; if (container_field.ast.tuple_like) break true;
} else false; } else false;
if (is_tuple) switch (layout) {
.Auto => {},
.Extern => return astgen.failNode(node, "extern tuples are not supported", .{}),
.Packed => return astgen.failNode(node, "packed tuples are not supported", .{}),
};
if (is_tuple) for (container_decl.ast.members) |member_node| { if (is_tuple) for (container_decl.ast.members) |member_node| {
switch (node_tags[member_node]) { switch (node_tags[member_node]) {
.container_field_init, .container_field_init,

View File

@ -20391,6 +20391,12 @@ fn reifyStruct(
const gpa = sema.gpa; const gpa = sema.gpa;
const ip = &mod.intern_pool; const ip = &mod.intern_pool;
if (is_tuple) switch (layout) {
.Extern => return sema.fail(block, src, "extern tuples are not supported", .{}),
.Packed => return sema.fail(block, src, "packed tuples are not supported", .{}),
.Auto => {},
};
// Because these three things each reference each other, `undefined` // Because these three things each reference each other, `undefined`
// placeholders are used before being set after the struct type gains an // placeholders are used before being set after the struct type gains an
// InternPool index. // InternPool index.

View File

@ -4164,8 +4164,8 @@ pub const WipFunction = struct {
@memcpy(extra.trail.nextMut(incoming_len, Block.Index, wip), blocks); @memcpy(extra.trail.nextMut(incoming_len, Block.Index, wip), blocks);
if (wip.builder.useLibLlvm()) { if (wip.builder.useLibLlvm()) {
const ExpectedContents = extern struct { const ExpectedContents = extern struct {
[expected_incoming_len]*llvm.Value, values: [expected_incoming_len]*llvm.Value,
[expected_incoming_len]*llvm.BasicBlock, blocks: [expected_incoming_len]*llvm.BasicBlock,
}; };
var stack align(@alignOf(ExpectedContents)) = var stack align(@alignOf(ExpectedContents)) =
std.heap.stackFallback(@sizeOf(ExpectedContents), wip.builder.gpa); std.heap.stackFallback(@sizeOf(ExpectedContents), wip.builder.gpa);

View File

@ -31,27 +31,6 @@ test "tuple declaration type info" {
try expect(!info.fields[1].is_comptime); try expect(!info.fields[1].is_comptime);
try expect(info.fields[1].alignment == @alignOf([]const u8)); try expect(info.fields[1].alignment == @alignOf([]const u8));
} }
{
const T = packed struct(u32) { u1, u30, u1 };
const info = @typeInfo(T).Struct;
try expect(std.mem.endsWith(u8, @typeName(T), "test.tuple declaration type info.T"));
try expect(info.layout == .Packed);
try expect(info.backing_integer == u32);
try expect(info.fields.len == 3);
try expect(info.decls.len == 0);
try expect(info.is_tuple);
try expectEqualStrings(info.fields[0].name, "0");
try expect(info.fields[0].type == u1);
try expectEqualStrings(info.fields[1].name, "1");
try expect(info.fields[1].type == u30);
try expectEqualStrings(info.fields[2].name, "2");
try expect(info.fields[2].type == u1);
}
} }
test "Tuple declaration usage" { test "Tuple declaration usage" {

View File

@ -51,7 +51,7 @@ comptime {
.alignment = 4, .alignment = 4,
}}, }},
.decls = &.{}, .decls = &.{},
.is_tuple = true, .is_tuple = false,
} }); } });
} }
comptime { comptime {
@ -65,7 +65,7 @@ comptime {
.alignment = 4, .alignment = 4,
}}, }},
.decls = &.{}, .decls = &.{},
.is_tuple = true, .is_tuple = false,
} }); } });
} }