Commit 1e7009a9d9

Martin Wickham <spexguy070@gmail.com>
2021-09-24 01:09:35
Fix error references across inline and comptime functions
1 parent 8f58e2d
Changed files (2)
src/Module.zig
@@ -248,6 +248,9 @@ pub const Export = struct {
     link: link.File.Export,
     /// The Decl that performs the export. Note that this is *not* the Decl being exported.
     owner_decl: *Decl,
+    /// The Decl containing the export statement.  Inline function calls
+    /// may cause this to be different from the owner_decl.
+    src_decl: *Decl,
     /// The Decl being exported. Note this is *not* the Decl performing the export.
     exported_decl: *Decl,
     status: enum {
@@ -261,8 +264,8 @@ pub const Export = struct {
 
     pub fn getSrcLoc(exp: Export) SrcLoc {
         return .{
-            .file_scope = exp.owner_decl.namespace.file_scope,
-            .parent_decl_node = exp.owner_decl.src_node,
+            .file_scope = exp.src_decl.namespace.file_scope,
+            .parent_decl_node = exp.src_decl.src_node,
             .lazy = exp.src,
         };
     }
@@ -1014,15 +1017,6 @@ pub const Scope = struct {
         return @fieldParentPtr(T, "base", base);
     }
 
-    /// Get the decl that is currently being analyzed
-    pub fn ownerDecl(scope: *Scope) ?*Decl {
-        return switch (scope.tag) {
-            .block => scope.cast(Block).?.sema.owner_decl,
-            .file => null,
-            .namespace => null,
-        };
-    }
-
     /// Get the decl which contains this decl, for the purposes of source reporting
     pub fn srcDecl(scope: *Scope) ?*Decl {
         return switch (scope.tag) {
@@ -3402,7 +3396,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
                 }
                 // The scope needs to have the decl in it.
                 const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
-                try mod.analyzeExport(&block_scope.base, export_src, options, decl);
+                try mod.analyzeExport(&block_scope, export_src, options, decl);
             }
             return type_changed or is_inline != prev_is_inline;
         }
@@ -3462,7 +3456,7 @@ fn semaDecl(mod: *Module, decl: *Decl) !bool {
         const export_src = src; // TODO point to the export token
         // The scope needs to have the decl in it.
         const options: std.builtin.ExportOptions = .{ .name = mem.spanZ(decl.name) };
-        try mod.analyzeExport(&block_scope.base, export_src, options, decl);
+        try mod.analyzeExport(&block_scope, export_src, options, decl);
     }
 
     return type_changed;
@@ -3931,7 +3925,7 @@ pub fn deleteUnusedDecl(mod: *Module, decl: *Decl) void {
 
 pub fn deleteAnonDecl(mod: *Module, scope: *Scope, decl: *Decl) void {
     log.debug("deleteAnonDecl {*} ({s})", .{ decl, decl.name });
-    const scope_decl = scope.ownerDecl().?;
+    const scope_decl = scope.srcDecl().?;
     assert(scope_decl.namespace.anon_decls.swapRemove(decl));
     decl.destroy(mod);
 }
@@ -4209,7 +4203,7 @@ pub fn getErrorValue(mod: *Module, name: []const u8) !std.StringHashMapUnmanaged
 
 pub fn analyzeExport(
     mod: *Module,
-    scope: *Scope,
+    block: *Scope.Block,
     src: LazySrcLoc,
     borrowed_options: std.builtin.ExportOptions,
     exported_decl: *Decl,
@@ -4217,7 +4211,7 @@ pub fn analyzeExport(
     try mod.ensureDeclAnalyzed(exported_decl);
     switch (exported_decl.ty.zigTypeTag()) {
         .Fn => {},
-        else => return mod.fail(scope, src, "unable to export type '{}'", .{exported_decl.ty}),
+        else => return mod.fail(&block.base, src, "unable to export type '{}'", .{exported_decl.ty}),
     }
 
     const gpa = mod.gpa;
@@ -4234,7 +4228,8 @@ pub fn analyzeExport(
     const section: ?[]const u8 = if (borrowed_options.section) |s| try gpa.dupe(u8, s) else null;
     errdefer if (section) |s| gpa.free(s);
 
-    const owner_decl = scope.ownerDecl().?;
+    const src_decl = block.src_decl;
+    const owner_decl = block.sema.owner_decl;
 
     log.debug("exporting Decl '{s}' as symbol '{s}' from Decl '{s}'", .{
         exported_decl.name, symbol_name, owner_decl.name,
@@ -4257,6 +4252,7 @@ pub fn analyzeExport(
             .spirv => .{ .spirv = {} },
         },
         .owner_decl = owner_decl,
+        .src_decl = src_decl,
         .exported_decl = exported_decl,
         .status = .in_progress,
     };
@@ -4287,38 +4283,38 @@ pub fn createAnonymousDeclNamed(
     typed_value: TypedValue,
     name: [:0]u8,
 ) !*Decl {
-    return mod.createAnonymousDeclFromDeclNamed(scope.ownerDecl().?, scope.srcScope(), typed_value, name);
+    return mod.createAnonymousDeclFromDeclNamed(scope.srcDecl().?, scope.srcScope(), typed_value, name);
 }
 
 pub fn createAnonymousDecl(mod: *Module, scope: *Scope, typed_value: TypedValue) !*Decl {
-    return mod.createAnonymousDeclFromDecl(scope.ownerDecl().?, scope.srcScope(), typed_value);
+    return mod.createAnonymousDeclFromDecl(scope.srcDecl().?, scope.srcScope(), typed_value);
 }
 
-pub fn createAnonymousDeclFromDecl(mod: *Module, owner_decl: *Decl, src_scope: ?*CaptureScope, tv: TypedValue) !*Decl {
+pub fn createAnonymousDeclFromDecl(mod: *Module, src_decl: *Decl, src_scope: ?*CaptureScope, tv: TypedValue) !*Decl {
     const name_index = mod.getNextAnonNameIndex();
     const name = try std.fmt.allocPrintZ(mod.gpa, "{s}__anon_{d}", .{
-        owner_decl.name, name_index,
+        src_decl.name, name_index,
     });
-    return mod.createAnonymousDeclFromDeclNamed(owner_decl, src_scope, tv, name);
+    return mod.createAnonymousDeclFromDeclNamed(src_decl, src_scope, tv, name);
 }
 
 /// Takes ownership of `name` even if it returns an error.
 pub fn createAnonymousDeclFromDeclNamed(
     mod: *Module,
-    owner_decl: *Decl,
+    src_decl: *Decl,
     src_scope: ?*CaptureScope,
     typed_value: TypedValue,
     name: [:0]u8,
 ) !*Decl {
     errdefer mod.gpa.free(name);
 
-    const namespace = owner_decl.namespace;
+    const namespace = src_decl.namespace;
     try namespace.anon_decls.ensureUnusedCapacity(mod.gpa, 1);
 
-    const new_decl = try mod.allocateNewDecl(namespace, owner_decl.src_node, src_scope);
+    const new_decl = try mod.allocateNewDecl(namespace, src_decl.src_node, src_scope);
 
     new_decl.name = name;
-    new_decl.src_line = owner_decl.src_line;
+    new_decl.src_line = src_decl.src_line;
     new_decl.ty = typed_value.ty;
     new_decl.val = typed_value.val;
     new_decl.align_val = Value.initTag(.null_value);
src/Sema.zig
@@ -2447,7 +2447,7 @@ fn zirExport(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileErro
     }
     const decl = try sema.lookupIdentifier(block, operand_src, decl_name);
     const options = try sema.resolveExportOptions(block, options_src, extra.options);
-    try sema.mod.analyzeExport(&block.base, src, options, decl);
+    try sema.mod.analyzeExport(block, src, options, decl);
 }
 
 fn zirExportValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {
@@ -2465,7 +2465,7 @@ fn zirExportValue(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) Compil
         .function => operand.val.castTag(.function).?.data.owner_decl,
         else => return sema.mod.fail(&block.base, operand_src, "TODO implement exporting arbitrary Value objects", .{}), // TODO put this Value into an anonymous Decl and then export it.
     };
-    try sema.mod.analyzeExport(&block.base, src, options, decl);
+    try sema.mod.analyzeExport(block, src, options, decl);
 }
 
 fn zirSetAlignStack(sema: *Sema, block: *Scope.Block, inst: Zir.Inst.Index) CompileError!void {