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.
This commit is contained in:
John Schmidt 2022-09-25 00:30:15 +02:00
parent 6cc2b26163
commit b6bda5183e
2 changed files with 30 additions and 2 deletions

View file

@ -1868,9 +1868,11 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS
errdefer msg.destroy(sema.gpa); errdefer msg.destroy(sema.gpa);
const decl_index = container_ty.getOwnerDeclOrNull() orelse break :msg msg; const decl_index = container_ty.getOwnerDeclOrNull() orelse break :msg msg;
const tree = try sema.getAstTree(block);
const decl = sema.mod.declPtr(decl_index); 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 field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);
const default_value_src: LazySrcLoc = .{ .node_offset_field_default = field_src.node_offset.x }; const default_value_src: LazySrcLoc = .{ .node_offset_field_default = field_src.node_offset.x };

View file

@ -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 // TODO test this in stage2, but we won't even try in stage1
//ctx.objErrStage1("inline fn calls itself indirectly", //ctx.objErrStage1("inline fn calls itself indirectly",
// \\export fn foo() void { // \\export fn foo() void {