authorgravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2022-09-24 02:23:22+02:00
committergravatar for john.schmidt.h@gmail.comJohn Schmidt <john.schmidt.h@gmail.com> 2022-09-25 10:28:48+02:00
log6cc2b2616365c2a216f3dd73837f405df094daab
treef15575f12a2a54a34418696a3c57e4e55ba95c10
parent6d7b0690a0e49819ffd92e330f0fd48a7abc0d16

sema: load the correct AST in addFieldErrNote

The enum 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. Closes #12950.

2 files changed, 33 insertions(+), 16 deletions(-)

src/Sema.zig+17-16
......@@ -1908,7 +1908,6 @@ fn errNote(
19081908
19091909fn addFieldErrNote(
19101910 sema: *Sema,
1911 block: *Block,
19121911 container_ty: Type,
19131912 field_index: usize,
19141913 parent: *Module.ErrorMsg,
......@@ -1918,7 +1917,10 @@ fn addFieldErrNote(
19181917 const mod = sema.mod;
19191918 const decl_index = container_ty.getOwnerDecl();
19201919 const decl = mod.declPtr(decl_index);
1921 const tree = try sema.getAstTree(block);
1920 const tree = decl.getFileScope().getTree(sema.gpa) catch |err| {
1921 log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});
1922 return error.AnalysisFail;
1923 };
19221924 const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);
19231925 try mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args);
19241926}
......@@ -9371,7 +9373,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
93719373
93729374 const field_name = operand_ty.enumFieldName(i);
93739375 try sema.addFieldErrNote(
9374 block,
93759376 operand_ty,
93769377 i,
93779378 msg,
......@@ -17379,7 +17380,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1737917380 const enum_ty = union_obj.tag_ty;
1738017381 for (names.keys()) |field_name| {
1738117382 const field_index = enum_ty.enumFieldIndex(field_name).?;
17382 try sema.addFieldErrNote(block, enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name});
17383 try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name});
1738317384 }
1738417385 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
1738517386 break :msg msg;
......@@ -17667,7 +17668,7 @@ fn reifyStruct(
1766717668 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {
1766817669 error.AnalysisFail => {
1766917670 const msg = sema.err orelse return err;
17670 try sema.addFieldErrNote(block, struct_ty, index, msg, "while checking this field", .{});
17671 try sema.addFieldErrNote(struct_ty, index, msg, "while checking this field", .{});
1767117672 return err;
1767217673 },
1767317674 else => return err,
......@@ -22270,7 +22271,7 @@ fn unionFieldPtr(
2227022271 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
2227122272 errdefer msg.destroy(sema.gpa);
2227222273
22273 try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
22274 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
2227422275 try sema.addDeclaredHereNote(msg, union_ty);
2227522276 break :msg msg;
2227622277 };
......@@ -25748,7 +25749,7 @@ fn coerceEnumToUnion(
2574825749 errdefer msg.destroy(sema.gpa);
2574925750
2575025751 const field_name = union_obj.fields.keys()[field_index];
25751 try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
25752 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
2575225753 try sema.addDeclaredHereNote(msg, union_ty);
2575325754 break :msg msg;
2575425755 };
......@@ -25762,7 +25763,7 @@ fn coerceEnumToUnion(
2576225763 });
2576325764 errdefer msg.destroy(sema.gpa);
2576425765
25765 try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
25766 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
2576625767 try sema.addDeclaredHereNote(msg, union_ty);
2576725768 break :msg msg;
2576825769 };
......@@ -25804,7 +25805,7 @@ fn coerceEnumToUnion(
2580425805 );
2580525806 msg = err_msg;
2580625807
25807 try sema.addFieldErrNote(block, union_ty, i, err_msg, "'noreturn' field here", .{});
25808 try sema.addFieldErrNote(union_ty, i, err_msg, "'noreturn' field here", .{});
2580825809 }
2580925810 }
2581025811 if (msg) |some| {
......@@ -25834,7 +25835,7 @@ fn coerceEnumToUnion(
2583425835 const field_name = field.key_ptr.*;
2583525836 const field_ty = field.value_ptr.ty;
2583625837 if (!field_ty.hasRuntimeBits()) continue;
25837 try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) });
25838 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) });
2583825839 }
2583925840 try sema.addDeclaredHereNote(msg, union_ty);
2584025841 break :msg msg;
......@@ -28056,7 +28057,7 @@ fn resolveStructLayout(
2805628057 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {
2805728058 error.AnalysisFail => {
2805828059 const msg = sema.err orelse return err;
28059 try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{});
28060 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
2806028061 return err;
2806128062 },
2806228063 else => return err,
......@@ -28076,7 +28077,7 @@ fn resolveStructLayout(
2807628077 _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) {
2807728078 error.AnalysisFail => {
2807828079 const msg = sema.err orelse return err;
28079 try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{});
28080 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
2808028081 return err;
2808128082 },
2808228083 else => return err,
......@@ -28215,7 +28216,7 @@ fn resolveUnionLayout(
2821528216 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {
2821628217 error.AnalysisFail => {
2821728218 const msg = sema.err orelse return err;
28218 try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{});
28219 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
2821928220 return err;
2822028221 },
2822128222 else => return err,
......@@ -29101,7 +29102,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
2910129102 const enum_ty = union_obj.tag_ty;
2910229103 for (names.keys()) |field_name| {
2910329104 const field_index = enum_ty.enumFieldIndex(field_name).?;
29104 try sema.addFieldErrNote(&block_scope, enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name});
29105 try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name});
2910529106 }
2910629107 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
2910729108 break :msg msg;
......@@ -29376,7 +29377,7 @@ pub fn typeHasOnePossibleValue(
2937629377 "struct '{}' depends on itself",
2937729378 .{ty.fmt(sema.mod)},
2937829379 );
29379 try sema.addFieldErrNote(block, resolved_ty, i, msg, "while checking this field", .{});
29380 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});
2938029381 return sema.failWithOwnedErrorMsg(msg);
2938129382 }
2938229383 if ((try sema.typeHasOnePossibleValue(block, src, field.ty)) == null) {
......@@ -29462,7 +29463,7 @@ pub fn typeHasOnePossibleValue(
2946229463 "union '{}' depends on itself",
2946329464 .{ty.fmt(sema.mod)},
2946429465 );
29465 try sema.addFieldErrNote(block, resolved_ty, 0, msg, "while checking this field", .{});
29466 try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{});
2946629467 return sema.failWithOwnedErrorMsg(msg);
2946729468 }
2946829469 const val_val = (try sema.typeHasOnePossibleValue(block, src, only_field.ty)) orelse
test/cases/compile_errors/unhandled_enum_value_in_switch_with_enum_declared_in_other_file.zig created+16
......@@ -0,0 +1,16 @@
1const std = @import("std");
2
3pub export fn entry1() void {
4 const order: std.math.Order = .lt;
5 switch (order) {}
6}
7
8// error
9// backend=stage2
10// target=native
11//
12// :5:5: error: switch must handle all possibilities
13// :?:?: note: unhandled enumeration value: 'lt'
14// :?:?: note: unhandled enumeration value: 'eq'
15// :?:?: note: unhandled enumeration value: 'gt'
16// :?:?: note: enum 'math.Order' declared here