authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-09-26 13:58:55+03:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-09-26 13:58:55+03:00
log8849792789331faec0caaca18822227ecdb9bc62
treea93d14f828db1e4e610eaa7dd1b8d71faf9c42d9
parent6d7b0690a0e49819ffd92e330f0fd48a7abc0d16
parentb6bda5183e44e88b53d3e51c3599d8889fb1bdb8
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #12951 from schmee/fix-add-field-err-note-oob

sema: load the correct AST in addFieldErrNote

3 files changed, 63 insertions(+), 18 deletions(-)

src/Sema.zig+21-18
...@@ -1868,9 +1868,11 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS...@@ -1868,9 +1868,11 @@ fn failWithInvalidComptimeFieldStore(sema: *Sema, block: *Block, init_src: LazyS
1868 errdefer msg.destroy(sema.gpa);1868 errdefer msg.destroy(sema.gpa);
18691869
1870 const decl_index = container_ty.getOwnerDeclOrNull() orelse break :msg msg;1870 const decl_index = container_ty.getOwnerDeclOrNull() orelse break :msg msg;
1871
1872 const tree = try sema.getAstTree(block);
1873 const decl = sema.mod.declPtr(decl_index);1871 const decl = sema.mod.declPtr(decl_index);
1872 const tree = decl.getFileScope().getTree(sema.gpa) catch |err| {
1873 log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});
1874 return error.AnalysisFail;
1875 };
1874 const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);1876 const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);
1875 const default_value_src: LazySrcLoc = .{ .node_offset_field_default = field_src.node_offset.x };1877 const default_value_src: LazySrcLoc = .{ .node_offset_field_default = field_src.node_offset.x };
18761878
...@@ -1908,7 +1910,6 @@ fn errNote(...@@ -1908,7 +1910,6 @@ fn errNote(
19081910
1909fn addFieldErrNote(1911fn addFieldErrNote(
1910 sema: *Sema,1912 sema: *Sema,
1911 block: *Block,
1912 container_ty: Type,1913 container_ty: Type,
1913 field_index: usize,1914 field_index: usize,
1914 parent: *Module.ErrorMsg,1915 parent: *Module.ErrorMsg,
...@@ -1918,7 +1919,10 @@ fn addFieldErrNote(...@@ -1918,7 +1919,10 @@ fn addFieldErrNote(
1918 const mod = sema.mod;1919 const mod = sema.mod;
1919 const decl_index = container_ty.getOwnerDecl();1920 const decl_index = container_ty.getOwnerDecl();
1920 const decl = mod.declPtr(decl_index);1921 const decl = mod.declPtr(decl_index);
1921 const tree = try sema.getAstTree(block);1922 const tree = decl.getFileScope().getTree(sema.gpa) catch |err| {
1923 log.err("unable to load AST to report compile error: {s}", .{@errorName(err)});
1924 return error.AnalysisFail;
1925 };
1922 const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);1926 const field_src = enumFieldSrcLoc(decl, tree.*, 0, field_index);
1923 try mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args);1927 try mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args);
1924}1928}
...@@ -9371,7 +9375,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError...@@ -9371,7 +9375,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
93719375
9372 const field_name = operand_ty.enumFieldName(i);9376 const field_name = operand_ty.enumFieldName(i);
9373 try sema.addFieldErrNote(9377 try sema.addFieldErrNote(
9374 block,
9375 operand_ty,9378 operand_ty,
9376 i,9379 i,
9377 msg,9380 msg,
...@@ -17379,7 +17382,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in...@@ -17379,7 +17382,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
17379 const enum_ty = union_obj.tag_ty;17382 const enum_ty = union_obj.tag_ty;
17380 for (names.keys()) |field_name| {17383 for (names.keys()) |field_name| {
17381 const field_index = enum_ty.enumFieldIndex(field_name).?;17384 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});17385 try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name});
17383 }17386 }
17384 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);17387 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
17385 break :msg msg;17388 break :msg msg;
...@@ -17667,7 +17670,7 @@ fn reifyStruct(...@@ -17667,7 +17670,7 @@ fn reifyStruct(
17667 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {17670 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {
17668 error.AnalysisFail => {17671 error.AnalysisFail => {
17669 const msg = sema.err orelse return err;17672 const msg = sema.err orelse return err;
17670 try sema.addFieldErrNote(block, struct_ty, index, msg, "while checking this field", .{});17673 try sema.addFieldErrNote(struct_ty, index, msg, "while checking this field", .{});
17671 return err;17674 return err;
17672 },17675 },
17673 else => return err,17676 else => return err,
...@@ -22270,7 +22273,7 @@ fn unionFieldPtr(...@@ -22270,7 +22273,7 @@ fn unionFieldPtr(
22270 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});22273 const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{});
22271 errdefer msg.destroy(sema.gpa);22274 errdefer msg.destroy(sema.gpa);
2227222275
22273 try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name});22276 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
22274 try sema.addDeclaredHereNote(msg, union_ty);22277 try sema.addDeclaredHereNote(msg, union_ty);
22275 break :msg msg;22278 break :msg msg;
22276 };22279 };
...@@ -25748,7 +25751,7 @@ fn coerceEnumToUnion(...@@ -25748,7 +25751,7 @@ fn coerceEnumToUnion(
25748 errdefer msg.destroy(sema.gpa);25751 errdefer msg.destroy(sema.gpa);
2574925752
25750 const field_name = union_obj.fields.keys()[field_index];25753 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});25754 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
25752 try sema.addDeclaredHereNote(msg, union_ty);25755 try sema.addDeclaredHereNote(msg, union_ty);
25753 break :msg msg;25756 break :msg msg;
25754 };25757 };
...@@ -25762,7 +25765,7 @@ fn coerceEnumToUnion(...@@ -25762,7 +25765,7 @@ fn coerceEnumToUnion(
25762 });25765 });
25763 errdefer msg.destroy(sema.gpa);25766 errdefer msg.destroy(sema.gpa);
2576425767
25765 try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name});25768 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name});
25766 try sema.addDeclaredHereNote(msg, union_ty);25769 try sema.addDeclaredHereNote(msg, union_ty);
25767 break :msg msg;25770 break :msg msg;
25768 };25771 };
...@@ -25804,7 +25807,7 @@ fn coerceEnumToUnion(...@@ -25804,7 +25807,7 @@ fn coerceEnumToUnion(
25804 );25807 );
25805 msg = err_msg;25808 msg = err_msg;
2580625809
25807 try sema.addFieldErrNote(block, union_ty, i, err_msg, "'noreturn' field here", .{});25810 try sema.addFieldErrNote(union_ty, i, err_msg, "'noreturn' field here", .{});
25808 }25811 }
25809 }25812 }
25810 if (msg) |some| {25813 if (msg) |some| {
...@@ -25834,7 +25837,7 @@ fn coerceEnumToUnion(...@@ -25834,7 +25837,7 @@ fn coerceEnumToUnion(
25834 const field_name = field.key_ptr.*;25837 const field_name = field.key_ptr.*;
25835 const field_ty = field.value_ptr.ty;25838 const field_ty = field.value_ptr.ty;
25836 if (!field_ty.hasRuntimeBits()) continue;25839 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) });25840 try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) });
25838 }25841 }
25839 try sema.addDeclaredHereNote(msg, union_ty);25842 try sema.addDeclaredHereNote(msg, union_ty);
25840 break :msg msg;25843 break :msg msg;
...@@ -28056,7 +28059,7 @@ fn resolveStructLayout(...@@ -28056,7 +28059,7 @@ fn resolveStructLayout(
28056 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {28059 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {
28057 error.AnalysisFail => {28060 error.AnalysisFail => {
28058 const msg = sema.err orelse return err;28061 const msg = sema.err orelse return err;
28059 try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{});28062 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
28060 return err;28063 return err;
28061 },28064 },
28062 else => return err,28065 else => return err,
...@@ -28076,7 +28079,7 @@ fn resolveStructLayout(...@@ -28076,7 +28079,7 @@ fn resolveStructLayout(
28076 _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) {28079 _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) {
28077 error.AnalysisFail => {28080 error.AnalysisFail => {
28078 const msg = sema.err orelse return err;28081 const msg = sema.err orelse return err;
28079 try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{});28082 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
28080 return err;28083 return err;
28081 },28084 },
28082 else => return err,28085 else => return err,
...@@ -28215,7 +28218,7 @@ fn resolveUnionLayout(...@@ -28215,7 +28218,7 @@ fn resolveUnionLayout(
28215 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {28218 sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) {
28216 error.AnalysisFail => {28219 error.AnalysisFail => {
28217 const msg = sema.err orelse return err;28220 const msg = sema.err orelse return err;
28218 try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{});28221 try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{});
28219 return err;28222 return err;
28220 },28223 },
28221 else => return err,28224 else => return err,
...@@ -29101,7 +29104,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {...@@ -29101,7 +29104,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void {
29101 const enum_ty = union_obj.tag_ty;29104 const enum_ty = union_obj.tag_ty;
29102 for (names.keys()) |field_name| {29105 for (names.keys()) |field_name| {
29103 const field_index = enum_ty.enumFieldIndex(field_name).?;29106 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});29107 try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name});
29105 }29108 }
29106 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);29109 try sema.addDeclaredHereNote(msg, union_obj.tag_ty);
29107 break :msg msg;29110 break :msg msg;
...@@ -29376,7 +29379,7 @@ pub fn typeHasOnePossibleValue(...@@ -29376,7 +29379,7 @@ pub fn typeHasOnePossibleValue(
29376 "struct '{}' depends on itself",29379 "struct '{}' depends on itself",
29377 .{ty.fmt(sema.mod)},29380 .{ty.fmt(sema.mod)},
29378 );29381 );
29379 try sema.addFieldErrNote(block, resolved_ty, i, msg, "while checking this field", .{});29382 try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{});
29380 return sema.failWithOwnedErrorMsg(msg);29383 return sema.failWithOwnedErrorMsg(msg);
29381 }29384 }
29382 if ((try sema.typeHasOnePossibleValue(block, src, field.ty)) == null) {29385 if ((try sema.typeHasOnePossibleValue(block, src, field.ty)) == null) {
...@@ -29462,7 +29465,7 @@ pub fn typeHasOnePossibleValue(...@@ -29462,7 +29465,7 @@ pub fn typeHasOnePossibleValue(
29462 "union '{}' depends on itself",29465 "union '{}' depends on itself",
29463 .{ty.fmt(sema.mod)},29466 .{ty.fmt(sema.mod)},
29464 );29467 );
29465 try sema.addFieldErrNote(block, resolved_ty, 0, msg, "while checking this field", .{});29468 try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{});
29466 return sema.failWithOwnedErrorMsg(msg);29469 return sema.failWithOwnedErrorMsg(msg);
29467 }29470 }
29468 const val_val = (try sema.typeHasOnePossibleValue(block, src, only_field.ty)) orelse29471 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
test/compile_errors.zig+26
...@@ -225,6 +225,32 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -225,6 +225,32 @@ pub fn addCases(ctx: *TestContext) !void {
225 });225 });
226 }226 }
227227
228 {
229 const case = ctx.obj("invalid store to comptime field", .{});
230 case.backend = .stage2;
231
232 case.addSourceFile("a.zig",
233 \\pub const S = struct {
234 \\ comptime foo: u32 = 1,
235 \\ bar: u32,
236 \\ pub fn foo(x: @This()) void {
237 \\ _ = x;
238 \\ }
239 \\};
240 );
241
242 case.addError(
243 \\const a = @import("a.zig");
244 \\
245 \\export fn entry() void {
246 \\ _ = a.S.foo(a.S{ .foo = 2, .bar = 2 });
247 \\}
248 , &[_][]const u8{
249 ":4:23: error: value stored in comptime field does not match the default value of the field",
250 ":2:25: note: default value set here",
251 });
252 }
253
228 // TODO test this in stage2, but we won't even try in stage1254 // TODO test this in stage2, but we won't even try in stage1
229 //ctx.objErrStage1("inline fn calls itself indirectly",255 //ctx.objErrStage1("inline fn calls itself indirectly",
230 // \\export fn foo() void {256 // \\export fn foo() void {