Commit b6bda5183e

John Schmidt <john.schmidt.h@gmail.com>
2022-09-25 00:30:15
sema: load the correct AST in failWithInvalidComptimeFieldStore
The container we want to get the fields from might not be declared in the same file as the block we are analyzing, so we should get the AST from the decl's file instead.
1 parent 6cc2b26
Changed files (2)
src/Sema.zig
@@ -1868,9 +1868,11 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS
         errdefer msg.destroy(sema.gpa);
 
         const decl_index = container_ty.getOwnerDeclOrNull() orelse break :msg msg;
-
-        const tree = try sema.getAstTree(block);
         const decl = sema.mod.declPtr(decl_index);
+        const tree = decl.getFileScope().getTree(sema.gpa) catch |err| {
+            log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});
+            return error.AnalysisFail;
+        };
         const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);
         const default_value_src: LazySrcLoc = .{ .node_offset_field_default = field_src.node_offset.x };
 
test/compile_errors.zig
@@ -225,6 +225,32 @@ pub fn addCases(ctx: *TestContext) !void {
         });
     }
 
+    {
+        const case = ctx.obj("invalid store to comptime field", .{});
+        case.backend = .stage2;
+
+        case.addSourceFile("a.zig",
+            \\pub const S = struct {
+            \\    comptime foo: u32 = 1,
+            \\    bar: u32,
+            \\    pub fn foo(x: @This()) void {
+            \\        _ = x;
+            \\    }
+            \\};
+        );
+
+        case.addError(
+            \\const a = @import("a.zig");
+            \\
+            \\export fn entry() void {
+            \\    _ = a.S.foo(a.S{ .foo = 2, .bar = 2 });
+            \\}
+        , &[_][]const u8{
+            ":4:23: error: value stored in comptime field does not match the default value of the field",
+            ":2:25: note: default value set here",
+        });
+    }
+
     // TODO test this in stage2, but we won't even try in stage1
     //ctx.objErrStage1("inline fn calls itself indirectly",
     //    \\export fn foo() void {