Commit c76b5c1a31

Veikka Tuominen <git@vexu.eu>
2022-08-03 18:55:27
stage2: correct node offset of nested declarations
1 parent d769fd0
src/AstGen.zig
@@ -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", .{});
                 }
src/Module.zig
@@ -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,
src/print_zir.zig
@@ -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);
src/Sema.zig
@@ -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| {
src/type.zig
@@ -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
test/cases/compile_errors/non_constant_expression_in_array_size.zig
@@ -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
test/cases/compile_errors/not_an_enum_type.zig
@@ -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
test/cases/compile_errors/tagName_on_invalid_value_of_non-exhaustive_enum.zig
@@ -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
test/cases/error_in_nested_declaration.zig
@@ -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'