stage2: correct node offset of nested declarations

This commit is contained in:
Veikka Tuominen 2022-08-03 19:55:27 +03:00
parent d769fd0102
commit c76b5c1a31
9 changed files with 106 additions and 114 deletions

View file

@ -4278,7 +4278,7 @@ fn structDeclInner(
var known_non_opv = false;
var known_comptime_only = false;
for (container_decl.ast.members) |member_node| {
const member = switch (try containerMember(gz, &namespace.base, &wip_members, member_node)) {
const member = switch (try containerMember(&block_scope, &namespace.base, &wip_members, member_node)) {
.decl => continue,
.field => |field| field,
};
@ -4445,7 +4445,7 @@ fn unionDeclInner(
defer wip_members.deinit();
for (members) |member_node| {
const member = switch (try containerMember(gz, &namespace.base, &wip_members, member_node)) {
const member = switch (try containerMember(&block_scope, &namespace.base, &wip_members, member_node)) {
.decl => continue,
.field => |field| field,
};
@ -4732,7 +4732,7 @@ fn containerDecl(
for (container_decl.ast.members) |member_node| {
if (member_node == counts.nonexhaustive_node)
continue;
const member = switch (try containerMember(gz, &namespace.base, &wip_members, member_node)) {
const member = switch (try containerMember(&block_scope, &namespace.base, &wip_members, member_node)) {
.decl => continue,
.field => |field| field,
};
@ -4810,13 +4810,26 @@ fn containerDecl(
};
defer namespace.deinit(gpa);
astgen.advanceSourceCursorToNode(node);
var block_scope: GenZir = .{
.parent = &namespace.base,
.decl_node_index = node,
.decl_line = astgen.source_line,
.astgen = astgen,
.force_comptime = true,
.in_defer = false,
.instructions = gz.instructions,
.instructions_top = gz.instructions.items.len,
};
defer block_scope.unstack();
const decl_count = try astgen.scanDecls(&namespace, container_decl.ast.members);
var wip_members = try WipMembers.init(gpa, &astgen.scratch, decl_count, 0, 0, 0);
defer wip_members.deinit();
for (container_decl.ast.members) |member_node| {
const res = try containerMember(gz, &namespace.base, &wip_members, member_node);
const res = try containerMember(&block_scope, &namespace.base, &wip_members, member_node);
if (res == .field) {
return astgen.failNode(member_node, "opaque types cannot have fields", .{});
}

View file

@ -853,8 +853,6 @@ pub const EmitH = struct {
pub const ErrorSet = struct {
/// The Decl that corresponds to the error set itself.
owner_decl: Decl.Index,
/// Offset from Decl node index, points to the error set AST node.
node_offset: i32,
/// The string bytes are stored in the owner Decl arena.
/// These must be in sorted order. See sortNames.
names: NameMap,
@ -866,7 +864,7 @@ pub const ErrorSet = struct {
return .{
.file_scope = owner_decl.getFileScope(),
.parent_decl_node = owner_decl.src_node,
.lazy = LazySrcLoc.nodeOffset(self.node_offset),
.lazy = LazySrcLoc.nodeOffset(0),
};
}
@ -893,8 +891,6 @@ pub const Struct = struct {
namespace: Namespace,
/// The Decl that corresponds to the struct itself.
owner_decl: Decl.Index,
/// Offset from `owner_decl`, points to the struct AST node.
node_offset: i32,
/// Index of the struct_decl ZIR instruction.
zir_index: Zir.Inst.Index,
@ -953,7 +949,7 @@ pub const Struct = struct {
return .{
.file_scope = owner_decl.getFileScope(),
.parent_decl_node = owner_decl.src_node,
.lazy = LazySrcLoc.nodeOffset(s.node_offset),
.lazy = LazySrcLoc.nodeOffset(0),
};
}
@ -968,7 +964,7 @@ pub const Struct = struct {
});
return s.srcLoc(mod);
};
const node = owner_decl.relativeToNodeIndex(s.node_offset);
const node = owner_decl.relativeToNodeIndex(0);
const node_tags = tree.nodes.items(.tag);
switch (node_tags[node]) {
.container_decl,
@ -1060,8 +1056,6 @@ pub const Struct = struct {
pub const EnumSimple = struct {
/// The Decl that corresponds to the enum itself.
owner_decl: Decl.Index,
/// Offset from `owner_decl`, points to the enum decl AST node.
node_offset: i32,
/// Set of field names in declaration order.
fields: NameMap,
@ -1072,7 +1066,7 @@ pub const EnumSimple = struct {
return .{
.file_scope = owner_decl.getFileScope(),
.parent_decl_node = owner_decl.src_node,
.lazy = LazySrcLoc.nodeOffset(self.node_offset),
.lazy = LazySrcLoc.nodeOffset(0),
};
}
};
@ -1083,8 +1077,6 @@ pub const EnumSimple = struct {
pub const EnumNumbered = struct {
/// The Decl that corresponds to the enum itself.
owner_decl: Decl.Index,
/// Offset from `owner_decl`, points to the enum decl AST node.
node_offset: i32,
/// An integer type which is used for the numerical value of the enum.
/// Whether zig chooses this type or the user specifies it, it is stored here.
tag_ty: Type,
@ -1103,7 +1095,7 @@ pub const EnumNumbered = struct {
return .{
.file_scope = owner_decl.getFileScope(),
.parent_decl_node = owner_decl.src_node,
.lazy = LazySrcLoc.nodeOffset(self.node_offset),
.lazy = LazySrcLoc.nodeOffset(0),
};
}
};
@ -1113,8 +1105,6 @@ pub const EnumNumbered = struct {
pub const EnumFull = struct {
/// The Decl that corresponds to the enum itself.
owner_decl: Decl.Index,
/// Offset from `owner_decl`, points to the enum decl AST node.
node_offset: i32,
/// An integer type which is used for the numerical value of the enum.
/// Whether zig chooses this type or the user specifies it, it is stored here.
tag_ty: Type,
@ -1137,7 +1127,7 @@ pub const EnumFull = struct {
return .{
.file_scope = owner_decl.getFileScope(),
.parent_decl_node = owner_decl.src_node,
.lazy = LazySrcLoc.nodeOffset(self.node_offset),
.lazy = LazySrcLoc.nodeOffset(0),
};
}
};
@ -1155,8 +1145,6 @@ pub const Union = struct {
namespace: Namespace,
/// The Decl that corresponds to the union itself.
owner_decl: Decl.Index,
/// Offset from `owner_decl`, points to the union decl AST node.
node_offset: i32,
/// Index of the union_decl ZIR instruction.
zir_index: Zir.Inst.Index,
@ -1203,7 +1191,7 @@ pub const Union = struct {
return .{
.file_scope = owner_decl.getFileScope(),
.parent_decl_node = owner_decl.src_node,
.lazy = LazySrcLoc.nodeOffset(self.node_offset),
.lazy = LazySrcLoc.nodeOffset(0),
};
}
@ -1218,7 +1206,7 @@ pub const Union = struct {
});
return u.srcLoc(mod);
};
const node = owner_decl.relativeToNodeIndex(u.node_offset);
const node = owner_decl.relativeToNodeIndex(0);
const node_tags = tree.nodes.items(.tag);
var buf: [2]Ast.Node.Index = undefined;
switch (node_tags[node]) {
@ -1410,8 +1398,6 @@ pub const Union = struct {
pub const Opaque = struct {
/// The Decl that corresponds to the opaque itself.
owner_decl: Decl.Index,
/// Offset from `owner_decl`, points to the opaque decl AST node.
node_offset: i32,
/// Represents the declarations inside this opaque.
namespace: Namespace,
@ -1420,7 +1406,7 @@ pub const Opaque = struct {
return .{
.file_scope = owner_decl.getFileScope(),
.parent_decl_node = owner_decl.src_node,
.lazy = LazySrcLoc.nodeOffset(self.node_offset),
.lazy = LazySrcLoc.nodeOffset(0),
};
}
@ -4337,7 +4323,6 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void {
struct_obj.* = .{
.owner_decl = undefined, // set below
.fields = .{},
.node_offset = 0, // it's the struct for the root file
.zir_index = undefined, // set below
.layout = .Auto,
.status = .none,

View file

@ -1818,10 +1818,10 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS
const tree = try sema.getAstTree(block);
const decl = sema.mod.declPtr(decl_index);
const field_src = enumFieldSrcLoc(decl, tree.*, container_ty.getNodeOffset(), field_index);
const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);
const default_value_src: LazySrcLoc = .{ .node_offset_field_default = field_src.node_offset.x };
try sema.errNote(block, default_value_src, msg, "default value set here", .{});
try sema.mod.errNoteNonLazy(default_value_src.toSrcLoc(decl), msg, "default value set here", .{});
break :msg msg;
};
return sema.failWithOwnedErrorMsg(msg);
@ -1866,7 +1866,7 @@ fn addFieldErrNote(
const decl_index = container_ty.getOwnerDecl();
const decl = mod.declPtr(decl_index);
const tree = try sema.getAstTree(block);
const field_src = enumFieldSrcLoc(decl, tree.*, container_ty.getNodeOffset(), field_index);
const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);
try mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args);
}
@ -2262,7 +2262,7 @@ fn zirStructDecl(
const struct_obj = try new_decl_arena_allocator.create(Module.Struct);
const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj);
const struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty);
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
.ty = Type.type,
.val = struct_val,
}, small.name_strategy, "struct", inst);
@ -2272,7 +2272,6 @@ fn zirStructDecl(
struct_obj.* = .{
.owner_decl = new_decl_index,
.fields = .{},
.node_offset = src.node_offset.x,
.zir_index = inst,
.layout = small.layout,
.status = .none,
@ -2294,6 +2293,7 @@ fn zirStructDecl(
fn createAnonymousDeclTypeNamed(
sema: *Sema,
block: *Block,
src: LazySrcLoc,
typed_value: TypedValue,
name_strategy: Zir.Inst.NameStrategy,
anon_prefix: []const u8,
@ -2303,7 +2303,8 @@ fn createAnonymousDeclTypeNamed(
const namespace = block.namespace;
const src_scope = block.wip_capture_scope;
const src_decl = mod.declPtr(block.src_decl);
const new_decl_index = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope);
const src_node = src_decl.relativeToNodeIndex(src.node_offset.x);
const new_decl_index = try mod.allocateNewDecl(namespace, src_node, src_scope);
errdefer mod.destroyDecl(new_decl_index);
switch (name_strategy) {
@ -2378,7 +2379,7 @@ fn createAnonymousDeclTypeNamed(
},
else => {},
};
return sema.createAnonymousDeclTypeNamed(block, typed_value, .anon, anon_prefix, null);
return sema.createAnonymousDeclTypeNamed(block, src, typed_value, .anon, anon_prefix, null);
},
}
}
@ -2442,7 +2443,7 @@ fn zirEnumDecl(
};
const enum_ty = Type.initPayload(&enum_ty_payload.base);
const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
.ty = Type.type,
.val = enum_val,
}, small.name_strategy, "enum", inst);
@ -2456,7 +2457,6 @@ fn zirEnumDecl(
.tag_ty_inferred = true,
.fields = .{},
.values = .{},
.node_offset = src.node_offset.x,
.namespace = .{
.parent = block.namespace,
.ty = enum_ty,
@ -2684,7 +2684,7 @@ fn zirUnionDecl(
const union_ty = Type.initPayload(&union_payload.base);
const union_val = try Value.Tag.ty.create(new_decl_arena_allocator, union_ty);
const mod = sema.mod;
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
.ty = Type.type,
.val = union_val,
}, small.name_strategy, "union", inst);
@ -2695,7 +2695,6 @@ fn zirUnionDecl(
.owner_decl = new_decl_index,
.tag_ty = Type.initTag(.@"null"),
.fields = .{},
.node_offset = src.node_offset.x,
.zir_index = inst,
.layout = small.layout,
.status = .none,
@ -2753,7 +2752,7 @@ fn zirOpaqueDecl(
};
const opaque_ty = Type.initPayload(&opaque_ty_payload.base);
const opaque_val = try Value.Tag.ty.create(new_decl_arena_allocator, opaque_ty);
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
.ty = Type.type,
.val = opaque_val,
}, small.name_strategy, "opaque", inst);
@ -2763,7 +2762,6 @@ fn zirOpaqueDecl(
opaque_obj.* = .{
.owner_decl = new_decl_index,
.node_offset = src.node_offset.x,
.namespace = .{
.parent = block.namespace,
.ty = opaque_ty,
@ -2802,7 +2800,7 @@ fn zirErrorSetDecl(
const error_set_ty = try Type.Tag.error_set.create(new_decl_arena_allocator, error_set);
const error_set_val = try Value.Tag.ty.create(new_decl_arena_allocator, error_set_ty);
const mod = sema.mod;
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
.ty = Type.type,
.val = error_set_val,
}, name_strategy, "error", inst);
@ -2827,7 +2825,6 @@ fn zirErrorSetDecl(
error_set.* = .{
.owner_decl = new_decl_index,
.node_offset = inst_data.src_node,
.names = names,
};
try new_decl.finalizeNewArena(&new_decl_arena);
@ -16336,7 +16333,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
};
const enum_ty = Type.initPayload(&enum_ty_payload.base);
const enum_val = try Value.Tag.ty.create(new_decl_arena_allocator, enum_ty);
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
.ty = Type.type,
.val = enum_val,
}, name_strategy, "enum", inst);
@ -16350,7 +16347,6 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
.tag_ty_inferred = false,
.fields = .{},
.values = .{},
.node_offset = src.node_offset.x,
.namespace = .{
.parent = block.namespace,
.ty = enum_ty,
@ -16433,7 +16429,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
};
const opaque_ty = Type.initPayload(&opaque_ty_payload.base);
const opaque_val = try Value.Tag.ty.create(new_decl_arena_allocator, opaque_ty);
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
.ty = Type.type,
.val = opaque_val,
}, name_strategy, "opaque", inst);
@ -16443,7 +16439,6 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
opaque_obj.* = .{
.owner_decl = new_decl_index,
.node_offset = src.node_offset.x,
.namespace = .{
.parent = block.namespace,
.ty = opaque_ty,
@ -16492,7 +16487,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
};
const union_ty = Type.initPayload(&union_payload.base);
const new_union_val = try Value.Tag.ty.create(new_decl_arena_allocator, union_ty);
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
.ty = Type.type,
.val = new_union_val,
}, name_strategy, "union", inst);
@ -16503,7 +16498,6 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
.owner_decl = new_decl_index,
.tag_ty = Type.initTag(.@"null"),
.fields = .{},
.node_offset = src.node_offset.x,
.zir_index = inst,
.layout = layout,
.status = .have_field_types,
@ -16798,7 +16792,7 @@ fn reifyStruct(
const struct_ty = try Type.Tag.@"struct".create(new_decl_arena_allocator, struct_obj);
const new_struct_val = try Value.Tag.ty.create(new_decl_arena_allocator, struct_ty);
const mod = sema.mod;
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, .{
const new_decl_index = try sema.createAnonymousDeclTypeNamed(block, src, .{
.ty = Type.type,
.val = new_struct_val,
}, name_strategy, "struct", inst);
@ -16808,7 +16802,6 @@ fn reifyStruct(
struct_obj.* = .{
.owner_decl = new_decl_index,
.fields = .{},
.node_offset = src.node_offset.x,
.zir_index = inst,
.layout = layout_val.toEnum(std.builtin.Type.ContainerLayout),
.status = .have_field_types,
@ -27241,7 +27234,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
const small = @bitCast(Zir.Inst.StructDecl.Small, extended.small);
var extra_index: usize = extended.operand;
const src = LazySrcLoc.nodeOffset(struct_obj.node_offset);
const src = LazySrcLoc.nodeOffset(0);
extra_index += @boolToInt(small.has_src_node);
const fields_len = if (small.has_fields_len) blk: {
@ -27360,12 +27353,12 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
if (gop.found_existing) {
const msg = msg: {
const tree = try sema.getAstTree(&block_scope);
const field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, field_i);
const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i);
const msg = try sema.errMsg(&block_scope, field_src, "duplicate struct field: '{s}'", .{field_name});
errdefer msg.destroy(gpa);
const prev_field_index = struct_obj.fields.getIndex(field_name).?;
const prev_field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, prev_field_index);
const prev_field_src = enumFieldSrcLoc(decl, tree.*, 0, prev_field_index);
try sema.mod.errNoteNonLazy(prev_field_src.toSrcLoc(decl), msg, "other field here", .{});
try sema.errNote(&block_scope, src, msg, "struct declared here", .{});
break :msg msg;
@ -27422,7 +27415,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
if (field_ty.zigTypeTag() == .Opaque) {
const msg = msg: {
const tree = try sema.getAstTree(&block_scope);
const field_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);
const field_src = enumFieldSrcLoc(decl, tree.*, 0, i);
const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
errdefer msg.destroy(sema.gpa);
@ -27434,7 +27427,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
if (struct_obj.layout == .Extern and !sema.validateExternType(field.ty, .other)) {
const msg = msg: {
const tree = try sema.getAstTree(&block_scope);
const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);
const fields_src = enumFieldSrcLoc(decl, tree.*, 0, i);
const msg = try sema.errMsg(&block_scope, fields_src, "extern structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
@ -27447,7 +27440,7 @@ fn semaStructFields(mod: *Module, struct_obj: *Module.Struct) CompileError!void
} else if (struct_obj.layout == .Packed and !(validatePackedType(field.ty))) {
const msg = msg: {
const tree = try sema.getAstTree(&block_scope);
const fields_src = enumFieldSrcLoc(decl, tree.*, struct_obj.node_offset, i);
const fields_src = enumFieldSrcLoc(decl, tree.*, 0, i);
const msg = try sema.errMsg(&block_scope, fields_src, "packed structs cannot contain fields of type '{}'", .{field.ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
@ -27504,7 +27497,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
const small = @bitCast(Zir.Inst.UnionDecl.Small, extended.small);
var extra_index: usize = extended.operand;
const src = LazySrcLoc.nodeOffset(union_obj.node_offset);
const src = LazySrcLoc.nodeOffset(0);
extra_index += @boolToInt(small.has_src_node);
const tag_type_ref: Zir.Inst.Ref = if (small.has_tag_type) blk: {
@ -27728,12 +27721,12 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
if (gop.found_existing) {
const msg = msg: {
const tree = try sema.getAstTree(&block_scope);
const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i);
const msg = try sema.errMsg(&block_scope, field_src, "duplicate union field: '{s}'", .{field_name});
errdefer msg.destroy(gpa);
const prev_field_index = union_obj.fields.getIndex(field_name).?;
const prev_field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, prev_field_index);
const prev_field_src = enumFieldSrcLoc(decl, tree.*, 0, prev_field_index);
try sema.mod.errNoteNonLazy(prev_field_src.toSrcLoc(decl), msg, "other field here", .{});
try sema.errNote(&block_scope, src, msg, "union declared here", .{});
break :msg msg;
@ -27746,7 +27739,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
if (!enum_has_field) {
const msg = msg: {
const tree = try sema.getAstTree(&block_scope);
const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i);
const msg = try sema.errMsg(&block_scope, field_src, "no field named '{s}' in enum '{}'", .{ field_name, union_obj.tag_ty.fmt(sema.mod) });
errdefer msg.destroy(sema.gpa);
try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
@ -27759,7 +27752,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
if (field_ty.zigTypeTag() == .Opaque) {
const msg = msg: {
const tree = try sema.getAstTree(&block_scope);
const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i);
const msg = try sema.errMsg(&block_scope, field_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
errdefer msg.destroy(sema.gpa);
@ -27771,7 +27764,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
if (union_obj.layout == .Extern and !sema.validateExternType(field_ty, .union_field)) {
const msg = msg: {
const tree = try sema.getAstTree(&block_scope);
const field_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_i);
const msg = try sema.errMsg(&block_scope, field_src, "extern unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
@ -27784,7 +27777,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
} else if (union_obj.layout == .Packed and !(validatePackedType(field_ty))) {
const msg = msg: {
const tree = try sema.getAstTree(&block_scope);
const fields_src = enumFieldSrcLoc(decl, tree.*, union_obj.node_offset, field_i);
const fields_src = enumFieldSrcLoc(decl, tree.*, 0, field_i);
const msg = try sema.errMsg(&block_scope, fields_src, "packed unions cannot contain fields of type '{}'", .{field_ty.fmt(sema.mod)});
errdefer msg.destroy(sema.gpa);
@ -27876,7 +27869,6 @@ fn generateUnionTagTypeNumbered(
.tag_ty = int_ty,
.fields = .{},
.values = .{},
.node_offset = 0,
};
// Here we pre-allocate the maps using the decl arena.
try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
@ -27934,7 +27926,6 @@ fn generateUnionTagTypeSimple(sema: *Sema, block: *Block, fields_len: usize, may
enum_obj.* = .{
.owner_decl = new_decl_index,
.fields = .{},
.node_offset = 0,
};
// Here we pre-allocate the maps using the decl arena.
try enum_obj.fields.ensureTotalCapacity(new_decl_arena_allocator, fields_len);
@ -28245,7 +28236,7 @@ fn enumFieldSrcLoc(
=> tree.containerDeclArg(enum_node),
// Container was constructed with `@Type`.
else => return LazySrcLoc.nodeOffset(node_offset),
else => return LazySrcLoc.nodeOffset(0),
};
var it_index: usize = 0;
for (container_decl.ast.members) |member_node| {

View file

@ -1245,6 +1245,10 @@ const Writer = struct {
if (decls_len == 0) {
try stream.writeAll("{}, ");
} else {
const prev_parent_decl_node = self.parent_decl_node;
if (src_node) |off| self.parent_decl_node = self.relativeToNodeIndex(off);
defer self.parent_decl_node = prev_parent_decl_node;
try stream.writeAll("{\n");
self.indent += 2;
extra_index = try self.writeDecls(stream, decls_len, extra_index);
@ -1415,6 +1419,10 @@ const Writer = struct {
if (decls_len == 0) {
try stream.writeAll("{}, ");
} else {
const prev_parent_decl_node = self.parent_decl_node;
if (src_node) |off| self.parent_decl_node = self.relativeToNodeIndex(off);
defer self.parent_decl_node = prev_parent_decl_node;
try stream.writeAll("{\n");
self.indent += 2;
extra_index = try self.writeDecls(stream, decls_len, extra_index);
@ -1662,6 +1670,10 @@ const Writer = struct {
if (decls_len == 0) {
try stream.writeAll("{}, ");
} else {
const prev_parent_decl_node = self.parent_decl_node;
if (src_node) |off| self.parent_decl_node = self.relativeToNodeIndex(off);
defer self.parent_decl_node = prev_parent_decl_node;
try stream.writeAll("{\n");
self.indent += 2;
extra_index = try self.writeDecls(stream, decls_len, extra_index);
@ -1755,6 +1767,10 @@ const Writer = struct {
if (decls_len == 0) {
try stream.writeAll("{})");
} else {
const prev_parent_decl_node = self.parent_decl_node;
if (src_node) |off| self.parent_decl_node = self.relativeToNodeIndex(off);
defer self.parent_decl_node = prev_parent_decl_node;
try stream.writeAll("{\n");
self.indent += 2;
_ = try self.writeDecls(stream, decls_len, extra_index);

View file

@ -5771,50 +5771,6 @@ pub const Type = extern union {
}
}
pub fn getNodeOffset(ty: Type) i32 {
switch (ty.tag()) {
.enum_full, .enum_nonexhaustive => {
const enum_full = ty.cast(Payload.EnumFull).?.data;
return enum_full.node_offset;
},
.enum_numbered => return ty.castTag(.enum_numbered).?.data.node_offset,
.enum_simple => {
const enum_simple = ty.castTag(.enum_simple).?.data;
return enum_simple.node_offset;
},
.@"struct" => {
const struct_obj = ty.castTag(.@"struct").?.data;
return struct_obj.node_offset;
},
.error_set => {
const error_set = ty.castTag(.error_set).?.data;
return error_set.node_offset;
},
.@"union", .union_safety_tagged, .union_tagged => {
const union_obj = ty.cast(Payload.Union).?.data;
return union_obj.node_offset;
},
.@"opaque" => {
const opaque_obj = ty.cast(Payload.Opaque).?.data;
return opaque_obj.node_offset;
},
.atomic_order,
.atomic_rmw_op,
.calling_convention,
.address_space,
.float_mode,
.reduce_op,
.call_options,
.prefetch_options,
.export_options,
.extern_options,
.type_info,
=> unreachable, // These need to be resolved earlier.
else => unreachable,
}
}
/// This enum does not directly correspond to `std.builtin.TypeId` because
/// it has extra enum tags in it, as a way of using less memory. For example,
/// even though Zig recognizes `*align(10) i32` and `*i32` both as Pointer types

View file

@ -11,4 +11,4 @@ export fn entry() usize { return @offsetOf(Foo, "y"); }
// target=native
//
// :5:25: error: cannot load runtime value in comptime block
// :2:15: note: called from here
// :2:12: note: called from here

View file

@ -17,4 +17,4 @@ const ExpectedVarDeclOrFn = struct {};
// target=native
//
// :4:9: error: expected type '@typeInfo(tmp.Error).Union.tag_type.?', found 'type'
// :8:1: note: enum declared here
// :8:15: note: enum declared here

View file

@ -9,4 +9,4 @@ test "enum" {
// is_test=1
//
// :3:9: error: no field with value '5' in enum 'test.enum.E'
// :1:1: note: declared here
// :2:15: note: declared here

View file

@ -0,0 +1,31 @@
const S = struct {
b: u32,
c: i32,
a: struct {
pub fn str(_: @This(), extra: []u32) []i32 {
return @bitCast([]i32, extra);
}
},
};
pub export fn entry() void {
var s: S = undefined;
_ = s.a.str(undefined);
}
const S2 = struct {
a: [*c]anyopaque,
};
pub export fn entry2() void {
var s: S2 = undefined;
_ = s;
}
// error
// backend=llvm
// target=native
//
// :17:12: error: C pointers cannot point to opaque types
// :6:29: error: cannot @bitCast to '[]i32'
// :6:29: note: use @ptrCast to cast from '[]u32'