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(...@@ -1908,7 +1908,6 @@ fn errNote(
19081908
1909fn addFieldErrNote(1909fn addFieldErrNote(
1910 sema: *Sema,1910 sema: *Sema,
1911 block: *Block,
1912 container_ty: Type,1911 container_ty: Type,
1913 field_index: usize,1912 field_index: usize,
1914 parent: *Module.ErrorMsg,1913 parent: *Module.ErrorMsg,
...@@ -1918,7 +1917,10 @@ fn addFieldErrNote(...@@ -1918,7 +1917,10 @@ fn addFieldErrNote(
1918 const mod = sema.mod;1917 const mod = sema.mod;
1919 const decl_index = container_ty.getOwnerDecl();1918 const decl_index = container_ty.getOwnerDecl();
1920 const decl = mod.declPtr(decl_index);1919 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 };
1922 const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);1924 const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);
1923 try mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args);1925 try mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args);
1924}1926}
...@@ -9371,7 +9373,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -9371,7 +9373,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
93719373
9372 const field_name = operand_ty.enumFieldName(i);9374 const field_name = operand_ty.enumFieldName(i);
9373 try sema.addFieldErrNote(9375 try sema.addFieldErrNote(
9374 block,
9375 operand_ty,9376 operand_ty,
9376 i,9377 i,
9377 msg,9378 msg,
...@@ -17379,7 +17380,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -17379,7 +17380,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
17379 const enum_ty = union_obj.tag_ty;17380 const enum_ty = union_obj.tag_ty;
17380 for (names.keys()) |field_name| {17381 for (names.keys()) |field_name| {
17381 const field_index = enum_ty.enumFieldIndex(field_name).?;17382 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});
17383 }17384 }
17384 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);17385 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
17385 break :msg msg;17386 break :msg msg;
...@@ -17667,7 +17668,7 @@ fn reifyStruct(...@@ -17667,7 +17668,7 @@ fn reifyStruct(
17667 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {17668 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {
17668 error.AnalysisFail => {17669 error.AnalysisFail => {
17669 const msg = sema.err orelse return err;17670 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", .{});
17671 return err;17672 return err;
17672 },17673 },
17673 else => return err,17674 else => return err,
...@@ -22270,7 +22271,7 @@ fn unionFieldPtr(...@@ -22270,7 +22271,7 @@ fn unionFieldPtr(
22270 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});22271 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
22271 errdefer msg.destroy(sema.gpa);22272 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});
22274 try sema.addDeclaredHereNote(msg, union_ty);22275 try sema.addDeclaredHereNote(msg, union_ty);
22275 break :msg msg;22276 break :msg msg;
22276 };22277 };
...@@ -25748,7 +25749,7 @@ fn coerceEnumToUnion(...@@ -25748,7 +25749,7 @@ fn coerceEnumToUnion(
25748 errdefer msg.destroy(sema.gpa);25749 errdefer msg.destroy(sema.gpa);
2574925750
25750 const field_name = union_obj.fields.keys()[field_index];25751 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});
25752 try sema.addDeclaredHereNote(msg, union_ty);25753 try sema.addDeclaredHereNote(msg, union_ty);
25753 break :msg msg;25754 break :msg msg;
25754 };25755 };
...@@ -25762,7 +25763,7 @@ fn coerceEnumToUnion(...@@ -25762,7 +25763,7 @@ fn coerceEnumToUnion(
25762 });25763 });
25763 errdefer msg.destroy(sema.gpa);25764 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});
25766 try sema.addDeclaredHereNote(msg, union_ty);25767 try sema.addDeclaredHereNote(msg, union_ty);
25767 break :msg msg;25768 break :msg msg;
25768 };25769 };
...@@ -25804,7 +25805,7 @@ fn coerceEnumToUnion(...@@ -25804,7 +25805,7 @@ fn coerceEnumToUnion(
25804 );25805 );
25805 msg = err_msg;25806 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", .{});
25808 }25809 }
25809 }25810 }
25810 if (msg) |some| {25811 if (msg) |some| {
...@@ -25834,7 +25835,7 @@ fn coerceEnumToUnion(...@@ -25834,7 +25835,7 @@ fn coerceEnumToUnion(
25834 const field_name = field.key_ptr.*;25835 const field_name = field.key_ptr.*;
25835 const field_ty = field.value_ptr.ty;25836 const field_ty = field.value_ptr.ty;
25836 if (!field_ty.hasRuntimeBits()) continue;25837 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) });
25838 }25839 }
25839 try sema.addDeclaredHereNote(msg, union_ty);25840 try sema.addDeclaredHereNote(msg, union_ty);
25840 break :msg msg;25841 break :msg msg;
...@@ -28056,7 +28057,7 @@ fn resolveStructLayout(...@@ -28056,7 +28057,7 @@ fn resolveStructLayout(
28056 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {28057 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {
28057 error.AnalysisFail => {28058 error.AnalysisFail => {
28058 const msg = sema.err orelse return err;28059 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", .{});
28060 return err;28061 return err;
28061 },28062 },
28062 else => return err,28063 else => return err,
...@@ -28076,7 +28077,7 @@ fn resolveStructLayout(...@@ -28076,7 +28077,7 @@ fn resolveStructLayout(
28076 _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) {28077 _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) {
28077 error.AnalysisFail => {28078 error.AnalysisFail => {
28078 const msg = sema.err orelse return err;28079 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", .{});
28080 return err;28081 return err;
28081 },28082 },
28082 else => return err,28083 else => return err,
...@@ -28215,7 +28216,7 @@ fn resolveUnionLayout(...@@ -28215,7 +28216,7 @@ fn resolveUnionLayout(
28215 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {28216 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {
28216 error.AnalysisFail => {28217 error.AnalysisFail => {
28217 const msg = sema.err orelse return err;28218 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", .{});
28219 return err;28220 return err;
28220 },28221 },
28221 else => return err,28222 else => return err,
...@@ -29101,7 +29102,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -29101,7 +29102,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
29101 const enum_ty = union_obj.tag_ty;29102 const enum_ty = union_obj.tag_ty;
29102 for (names.keys()) |field_name| {29103 for (names.keys()) |field_name| {
29103 const field_index = enum_ty.enumFieldIndex(field_name).?;29104 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});
29105 }29106 }
29106 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);29107 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
29107 break :msg msg;29108 break :msg msg;
...@@ -29376,7 +29377,7 @@ pub fn typeHasOnePossibleValue(...@@ -29376,7 +29377,7 @@ pub fn typeHasOnePossibleValue(
29376 "struct '{}' depends on itself",29377 "struct '{}' depends on itself",
29377 .{ty.fmt(sema.mod)},29378 .{ty.fmt(sema.mod)},
29378 );29379 );
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", .{});
29380 return sema.failWithOwnedErrorMsg(msg);29381 return sema.failWithOwnedErrorMsg(msg);
29381 }29382 }
29382 if ((try sema.typeHasOnePossibleValue(block, src, field.ty)) == null) {29383 if ((try sema.typeHasOnePossibleValue(block, src, field.ty)) == null) {
...@@ -29462,7 +29463,7 @@ pub fn typeHasOnePossibleValue(...@@ -29462,7 +29463,7 @@ pub fn typeHasOnePossibleValue(
29462 "union '{}' depends on itself",29463 "union '{}' depends on itself",
29463 .{ty.fmt(sema.mod)},29464 .{ty.fmt(sema.mod)},
29464 );29465 );
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", .{});
29466 return sema.failWithOwnedErrorMsg(msg);29467 return sema.failWithOwnedErrorMsg(msg);
29467 }29468 }
29468 const val_val = (try sema.typeHasOnePossibleValue(block, src, only_field.ty)) orelse29469 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