diff --git a/src/Sema.zig b/src/Sema.zig index a36e1d9a02..72a5cb518f 100644 --- a/src/Sema.zig +++ b/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 }; @@ -1908,7 +1910,6 @@ fn errNote( fn addFieldErrNote( sema: *Sema, - block: *Block, container_ty: Type, field_index: usize, parent: *Module.ErrorMsg, @@ -1918,7 +1919,10 @@ fn addFieldErrNote( const mod = sema.mod; const decl_index = container_ty.getOwnerDecl(); const decl = mod.declPtr(decl_index); - const tree = try sema.getAstTree(block); + 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); try mod.errNoteNonLazy(field_src.toSrcLoc(decl), parent, format, args); } @@ -9371,7 +9375,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError const field_name = operand_ty.enumFieldName(i); try sema.addFieldErrNote( - block, operand_ty, i, msg, @@ -17379,7 +17382,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in const enum_ty = union_obj.tag_ty; for (names.keys()) |field_name| { const field_index = enum_ty.enumFieldIndex(field_name).?; - try sema.addFieldErrNote(block, enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name}); + try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name}); } try sema.addDeclaredHereNote(msg, union_obj.tag_ty); break :msg msg; @@ -17667,7 +17670,7 @@ fn reifyStruct( sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) { error.AnalysisFail => { const msg = sema.err orelse return err; - try sema.addFieldErrNote(block, struct_ty, index, msg, "while checking this field", .{}); + try sema.addFieldErrNote(struct_ty, index, msg, "while checking this field", .{}); return err; }, else => return err, @@ -22270,7 +22273,7 @@ fn unionFieldPtr( const msg = try sema.errMsg(block, src, "cannot initialize 'noreturn' field of union", .{}); errdefer msg.destroy(sema.gpa); - try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name}); + try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name}); try sema.addDeclaredHereNote(msg, union_ty); break :msg msg; }; @@ -25748,7 +25751,7 @@ fn coerceEnumToUnion( errdefer msg.destroy(sema.gpa); const field_name = union_obj.fields.keys()[field_index]; - try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name}); + try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name}); try sema.addDeclaredHereNote(msg, union_ty); break :msg msg; }; @@ -25762,7 +25765,7 @@ fn coerceEnumToUnion( }); errdefer msg.destroy(sema.gpa); - try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' declared here", .{field_name}); + try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' declared here", .{field_name}); try sema.addDeclaredHereNote(msg, union_ty); break :msg msg; }; @@ -25804,7 +25807,7 @@ fn coerceEnumToUnion( ); msg = err_msg; - try sema.addFieldErrNote(block, union_ty, i, err_msg, "'noreturn' field here", .{}); + try sema.addFieldErrNote(union_ty, i, err_msg, "'noreturn' field here", .{}); } } if (msg) |some| { @@ -25834,7 +25837,7 @@ fn coerceEnumToUnion( const field_name = field.key_ptr.*; const field_ty = field.value_ptr.ty; if (!field_ty.hasRuntimeBits()) continue; - try sema.addFieldErrNote(block, union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) }); + try sema.addFieldErrNote(union_ty, field_index, msg, "field '{s}' has type '{}'", .{ field_name, field_ty.fmt(sema.mod) }); } try sema.addDeclaredHereNote(msg, union_ty); break :msg msg; @@ -28056,7 +28059,7 @@ fn resolveStructLayout( sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) { error.AnalysisFail => { const msg = sema.err orelse return err; - try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{}); + try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{}); return err; }, else => return err, @@ -28076,7 +28079,7 @@ fn resolveStructLayout( _ = sema.typeRequiresComptime(field.ty) catch |err| switch (err) { error.AnalysisFail => { const msg = sema.err orelse return err; - try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{}); + try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{}); return err; }, else => return err, @@ -28215,7 +28218,7 @@ fn resolveUnionLayout( sema.resolveTypeLayout(block, src, field.ty) catch |err| switch (err) { error.AnalysisFail => { const msg = sema.err orelse return err; - try sema.addFieldErrNote(block, ty, i, msg, "while checking this field", .{}); + try sema.addFieldErrNote(ty, i, msg, "while checking this field", .{}); return err; }, else => return err, @@ -29101,7 +29104,7 @@ fn semaUnionFields(mod: *Module, union_obj: *Module.Union) CompileError!void { const enum_ty = union_obj.tag_ty; for (names.keys()) |field_name| { const field_index = enum_ty.enumFieldIndex(field_name).?; - try sema.addFieldErrNote(&block_scope, enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name}); + try sema.addFieldErrNote(enum_ty, field_index, msg, "field '{s}' missing, declared here", .{field_name}); } try sema.addDeclaredHereNote(msg, union_obj.tag_ty); break :msg msg; @@ -29376,7 +29379,7 @@ pub fn typeHasOnePossibleValue( "struct '{}' depends on itself", .{ty.fmt(sema.mod)}, ); - try sema.addFieldErrNote(block, resolved_ty, i, msg, "while checking this field", .{}); + try sema.addFieldErrNote(resolved_ty, i, msg, "while checking this field", .{}); return sema.failWithOwnedErrorMsg(msg); } if ((try sema.typeHasOnePossibleValue(block, src, field.ty)) == null) { @@ -29462,7 +29465,7 @@ pub fn typeHasOnePossibleValue( "union '{}' depends on itself", .{ty.fmt(sema.mod)}, ); - try sema.addFieldErrNote(block, resolved_ty, 0, msg, "while checking this field", .{}); + try sema.addFieldErrNote(resolved_ty, 0, msg, "while checking this field", .{}); return sema.failWithOwnedErrorMsg(msg); } const val_val = (try sema.typeHasOnePossibleValue(block, src, only_field.ty)) orelse diff --git a/test/cases/compile_errors/unhandled_enum_value_in_switch_with_enum_declared_in_other_file.zig b/test/cases/compile_errors/unhandled_enum_value_in_switch_with_enum_declared_in_other_file.zig new file mode 100644 index 0000000000..d64127a9d5 --- /dev/null +++ b/test/cases/compile_errors/unhandled_enum_value_in_switch_with_enum_declared_in_other_file.zig @@ -0,0 +1,16 @@ +const std = @import("std"); + +pub export fn entry1() void { + const order: std.math.Order = .lt; + switch (order) {} +} + +// error +// backend=stage2 +// target=native +// +// :5:5: error: switch must handle all possibilities +// :?:?: note: unhandled enumeration value: 'lt' +// :?:?: note: unhandled enumeration value: 'eq' +// :?:?: note: unhandled enumeration value: 'gt' +// :?:?: note: enum 'math.Order' declared here diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 60de07d1e3..96df66d081 100644 --- a/test/compile_errors.zig +++ b/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 {