authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-01-15 20:01:26+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-12 12:54:32-08:00
log51d67c7c8f20e89b70a62f0b82abf77a95868bec
tree7ff92d1a773e1dbf23cc3b346f9c8d95e11c6472
parentfad5e7a997344eddc45511df581472acaf0e880e

Sema: add declared here notes in `fail`

This ensures that the note is added in more places and that `errMsg` needs to be used in fewer places.

9 files changed, 73 insertions(+), 193 deletions(-)

src/Sema.zig+60-192
......@@ -2507,6 +2507,11 @@ pub fn fail(
25072507 args: anytype,
25082508) CompileError {
25092509 const err_msg = try sema.errMsg(block, src, format, args);
2510 inline for (args) |arg| {
2511 if (@TypeOf(arg) == Type.Formatter) {
2512 try addDeclaredHereNote(sema, err_msg, arg.data.ty);
2513 }
2514 }
25102515 return sema.failWithOwnedErrorMsg(block, err_msg);
25112516}
25122517
......@@ -5341,24 +5346,15 @@ fn failWithBadMemberAccess(
53415346 .Enum => "enum",
53425347 else => unreachable,
53435348 };
5344 const msg = msg: {
5345 const msg = blk: {
5346 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {
5347 break :blk try sema.errMsg(block, field_src, "root struct of file '{}' has no member named '{}'", .{
5348 agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),
5349 });
5350 };
5351
5352 break :blk try sema.errMsg(block, field_src, "{s} '{}' has no member named '{}'", .{
5353 kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),
5354 });
5355 };
5356
5357 errdefer msg.destroy(sema.gpa);
5358 try sema.addDeclaredHereNote(msg, agg_ty);
5359 break :msg msg;
5349 if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {
5350 return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{
5351 agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),
5352 });
53605353 };
5361 return sema.failWithOwnedErrorMsg(block, msg);
5354
5355 return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{
5356 kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),
5357 });
53625358}
53635359
53645360fn failWithBadStructFieldAccess(
......@@ -8689,35 +8685,17 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
86898685 if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
86908686 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
86918687 }
8692 const msg = msg: {
8693 const msg = try sema.errMsg(
8694 block,
8695 src,
8696 "int value '{}' out of range of non-exhaustive enum '{}'",
8697 .{ int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod) },
8698 );
8699 errdefer msg.destroy(sema.gpa);
8700 try sema.addDeclaredHereNote(msg, dest_ty);
8701 break :msg msg;
8702 };
8703 return sema.failWithOwnedErrorMsg(block, msg);
8688 return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{
8689 int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod),
8690 });
87048691 }
87058692 if (int_val.isUndef(mod)) {
87068693 return sema.failWithUseOfUndef(block, operand_src);
87078694 }
87088695 if (!(try sema.enumHasInt(dest_ty, int_val))) {
8709 const msg = msg: {
8710 const msg = try sema.errMsg(
8711 block,
8712 src,
8713 "enum '{}' has no tag with value '{}'",
8714 .{ dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod) },
8715 );
8716 errdefer msg.destroy(sema.gpa);
8717 try sema.addDeclaredHereNote(msg, dest_ty);
8718 break :msg msg;
8719 };
8720 return sema.failWithOwnedErrorMsg(block, msg);
8696 return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{
8697 dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod),
8698 });
87218699 }
87228700 return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
87238701 }
......@@ -9401,16 +9379,9 @@ fn funcCommon(
94019379 }
94029380 if (!param_ty.isValidParamType(mod)) {
94039381 const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";
9404 const msg = msg: {
9405 const msg = try sema.errMsg(block, param_src, "parameter of {s}type '{}' not allowed", .{
9406 opaque_str, param_ty.fmt(mod),
9407 });
9408 errdefer msg.destroy(sema.gpa);
9409
9410 try sema.addDeclaredHereNote(msg, param_ty);
9411 break :msg msg;
9412 };
9413 return sema.failWithOwnedErrorMsg(block, msg);
9382 return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
9383 opaque_str, param_ty.fmt(mod),
9384 });
94149385 }
94159386 if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) {
94169387 const msg = msg: {
......@@ -9690,16 +9661,9 @@ fn finishFunc(
96909661
96919662 if (!return_type.isValidReturnType(mod)) {
96929663 const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else "";
9693 const msg = msg: {
9694 const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{
9695 opaque_str, return_type.fmt(mod),
9696 });
9697 errdefer msg.destroy(gpa);
9698
9699 try sema.addDeclaredHereNote(msg, return_type);
9700 break :msg msg;
9701 };
9702 return sema.failWithOwnedErrorMsg(block, msg);
9664 return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{
9665 opaque_str, return_type.fmt(mod),
9666 });
97039667 }
97049668 if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and
97059669 !try sema.validateExternType(return_type, .ret_ty))
......@@ -10848,15 +10812,9 @@ const SwitchProngAnalysis = struct {
1084810812 else => unreachable,
1084910813 };
1085010814 const capture_src = raw_tag_capture_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, .none);
10851 const msg = msg: {
10852 const msg = try sema.errMsg(block, capture_src, "cannot capture tag of non-union type '{}'", .{
10853 operand_ty.fmt(mod),
10854 });
10855 errdefer msg.destroy(sema.gpa);
10856 try sema.addDeclaredHereNote(msg, operand_ty);
10857 break :msg msg;
10858 };
10859 return sema.failWithOwnedErrorMsg(block, msg);
10815 return sema.fail(block, capture_src, "cannot capture tag of non-union type '{}'", .{
10816 operand_ty.fmt(mod),
10817 });
1086010818 }
1086110819 assert(inline_case_capture != .none);
1086210820 return inline_case_capture;
......@@ -19824,13 +19782,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1982419782 const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
1982519783 const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
1982619784 if (union_ty.zigTypeTag(sema.mod) != .Union) {
19827 const msg = msg: {
19828 const msg = try sema.errMsg(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(sema.mod)});
19829 errdefer msg.destroy(sema.gpa);
19830 try sema.addDeclaredHereNote(msg, union_ty);
19831 break :msg msg;
19832 };
19833 return sema.failWithOwnedErrorMsg(block, msg);
19785 return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(sema.mod)});
1983419786 }
1983519787 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{
1983619788 .needed_comptime_reason = "name of field being initialized must be comptime-known",
......@@ -20941,17 +20893,8 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2094120893 return sema.addStrLit(ip.stringToSlice(tag_name));
2094220894 },
2094320895 .Enum => operand_ty,
20944 .Union => operand_ty.unionTagType(mod) orelse {
20945 const msg = msg: {
20946 const msg = try sema.errMsg(block, src, "union '{}' is untagged", .{
20947 operand_ty.fmt(sema.mod),
20948 });
20949 errdefer msg.destroy(sema.gpa);
20950 try sema.addDeclaredHereNote(msg, operand_ty);
20951 break :msg msg;
20952 };
20953 return sema.failWithOwnedErrorMsg(block, msg);
20954 },
20896 .Union => operand_ty.unionTagType(mod) orelse
20897 return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(sema.mod)}),
2095520898 else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{
2095620899 operand_ty.fmt(mod),
2095720900 }),
......@@ -21567,16 +21510,9 @@ fn zirReify(
2156721510 if (enum_tag_ty != .none) {
2156821511 const tag_info = ip.indexToKey(enum_tag_ty).enum_type;
2156921512 const enum_index = tag_info.nameIndex(ip, field_name) orelse {
21570 const msg = msg: {
21571 const msg = try sema.errMsg(block, src, "no field named '{}' in enum '{}'", .{
21572 field_name.fmt(ip),
21573 Type.fromInterned(enum_tag_ty).fmt(mod),
21574 });
21575 errdefer msg.destroy(gpa);
21576 try sema.addDeclaredHereNote(msg, Type.fromInterned(enum_tag_ty));
21577 break :msg msg;
21578 };
21579 return sema.failWithOwnedErrorMsg(block, msg);
21513 return sema.fail(block, src, "no field named '{}' in enum '{}'", .{
21514 field_name.fmt(ip), Type.fromInterned(enum_tag_ty).fmt(mod),
21515 });
2158021516 };
2158121517 assert(explicit_tags_seen.len == tag_info.names.len);
2158221518 // No check for duplicate because the check already happened in order
......@@ -22447,19 +22383,9 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2244722383 break :disjoint true;
2244822384 };
2244922385 if (disjoint and dest_tag != .ErrorUnion) {
22450 const msg = msg: {
22451 const msg = try sema.errMsg(
22452 block,
22453 src,
22454 "error sets '{}' and '{}' have no common errors",
22455 .{ operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod) },
22456 );
22457 errdefer msg.destroy(sema.gpa);
22458 try sema.addDeclaredHereNote(msg, operand_ty);
22459 try sema.addDeclaredHereNote(msg, dest_ty);
22460 break :msg msg;
22461 };
22462 return sema.failWithOwnedErrorMsg(block, msg);
22386 return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{
22387 operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod),
22388 });
2246322389 }
2246422390
2246522391 if (maybe_operand_val) |val| {
......@@ -22473,18 +22399,9 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
2247322399 error_name = operand_val.err.name;
2247422400 }
2247522401 if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) {
22476 const msg = msg: {
22477 const msg = try sema.errMsg(
22478 block,
22479 src,
22480 "'error.{}' not a member of error set '{}'",
22481 .{ error_name.fmt(ip), dest_ty.fmt(sema.mod) },
22482 );
22483 errdefer msg.destroy(sema.gpa);
22484 try sema.addDeclaredHereNote(msg, dest_ty);
22485 break :msg msg;
22486 };
22487 return sema.failWithOwnedErrorMsg(block, msg);
22402 return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{
22403 error_name.fmt(ip), dest_ty.fmt(sema.mod),
22404 });
2248822405 }
2248922406 }
2249022407
......@@ -23257,15 +23174,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
2325723174 try sema.resolveTypeLayout(ty);
2325823175 switch (ty.zigTypeTag(mod)) {
2325923176 .Struct => {},
23260 else => {
23261 const msg = msg: {
23262 const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)});
23263 errdefer msg.destroy(sema.gpa);
23264 try sema.addDeclaredHereNote(msg, ty);
23265 break :msg msg;
23266 };
23267 return sema.failWithOwnedErrorMsg(block, msg);
23268 },
23177 else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}),
2326923178 }
2327023179
2327123180 const field_index = if (ty.isTuple(mod)) blk: {
......@@ -24708,23 +24617,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
2470824617 } orelse return sema.fail(block, ptr_src, "pointer value not based on parent struct", .{});
2470924618
2471024619 if (field.index != field_index) {
24711 const msg = msg: {
24712 const msg = try sema.errMsg(
24713 block,
24714 src,
24715 "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'",
24716 .{
24717 field_name.fmt(ip),
24718 field_index,
24719 field.index,
24720 parent_ty.fmt(sema.mod),
24721 },
24722 );
24723 errdefer msg.destroy(sema.gpa);
24724 try sema.addDeclaredHereNote(msg, parent_ty);
24725 break :msg msg;
24726 };
24727 return sema.failWithOwnedErrorMsg(block, msg);
24620 return sema.fail(block, src, "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{
24621 field_name.fmt(ip), field_index, field.index, parent_ty.fmt(sema.mod),
24622 });
2472824623 }
2472924624 return Air.internedToRef(field.base);
2473024625 }
......@@ -26916,15 +26811,9 @@ fn fieldVal(
2691626811 switch (ip.indexToKey(child_type.toIntern())) {
2691726812 .error_set_type => |error_set_type| blk: {
2691826813 if (error_set_type.nameIndex(ip, field_name) != null) break :blk;
26919 const msg = msg: {
26920 const msg = try sema.errMsg(block, src, "no error named '{}' in '{}'", .{
26921 field_name.fmt(ip), child_type.fmt(mod),
26922 });
26923 errdefer msg.destroy(sema.gpa);
26924 try sema.addDeclaredHereNote(msg, child_type);
26925 break :msg msg;
26926 };
26927 return sema.failWithOwnedErrorMsg(block, msg);
26814 return sema.fail(block, src, "no error named '{}' in '{}'", .{
26815 field_name.fmt(ip), child_type.fmt(mod),
26816 });
2692826817 },
2692926818 .inferred_error_set_type => {
2693026819 return sema.fail(block, src, "TODO handle inferred error sets here", .{});
......@@ -29072,18 +28961,9 @@ fn coerceExtra(
2907228961 const val = try sema.resolveConstDefinedValue(block, .unneeded, inst, undefined);
2907328962 const string = mod.intern_pool.indexToKey(val.toIntern()).enum_literal;
2907428963 const field_index = dest_ty.enumFieldIndex(string, mod) orelse {
29075 const msg = msg: {
29076 const msg = try sema.errMsg(
29077 block,
29078 inst_src,
29079 "no field named '{}' in enum '{}'",
29080 .{ string.fmt(&mod.intern_pool), dest_ty.fmt(mod) },
29081 );
29082 errdefer msg.destroy(sema.gpa);
29083 try sema.addDeclaredHereNote(msg, dest_ty);
29084 break :msg msg;
29085 };
29086 return sema.failWithOwnedErrorMsg(block, msg);
28964 return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{
28965 string.fmt(&mod.intern_pool), dest_ty.fmt(mod),
28966 });
2908728967 };
2908828968 return Air.internedToRef((try mod.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern());
2908928969 },
......@@ -31718,15 +31598,9 @@ fn coerceEnumToUnion(
3171831598 const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
3171931599 if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
3172031600 const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse {
31721 const msg = msg: {
31722 const msg = try sema.errMsg(block, inst_src, "union '{}' has no tag with value '{}'", .{
31723 union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod),
31724 });
31725 errdefer msg.destroy(sema.gpa);
31726 try sema.addDeclaredHereNote(msg, union_ty);
31727 break :msg msg;
31728 };
31729 return sema.failWithOwnedErrorMsg(block, msg);
31601 return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{
31602 union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod),
31603 });
3173031604 };
3173131605
3173231606 const union_obj = mod.typeToUnion(union_ty).?;
......@@ -37202,19 +37076,13 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
3720237076 if (explicit_tags_seen.len > 0) {
3720337077 const tag_info = ip.indexToKey(union_type.tagTypePtr(ip).*).enum_type;
3720437078 const enum_index = tag_info.nameIndex(ip, field_name) orelse {
37205 const msg = msg: {
37206 const ty_src = mod.fieldSrcLoc(union_type.decl, .{
37207 .index = field_i,
37208 .range = .name,
37209 }).lazy;
37210 const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{}' in enum '{}'", .{
37211 field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(mod),
37212 });
37213 errdefer msg.destroy(sema.gpa);
37214 try sema.addDeclaredHereNote(msg, Type.fromInterned(union_type.tagTypePtr(ip).*));
37215 break :msg msg;
37216 };
37217 return sema.failWithOwnedErrorMsg(&block_scope, msg);
37079 const ty_src = mod.fieldSrcLoc(union_type.decl, .{
37080 .index = field_i,
37081 .range = .name,
37082 }).lazy;
37083 return sema.fail(&block_scope, ty_src, "no field named '{}' in enum '{}'", .{
37084 field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(mod),
37085 });
3721837086 };
3721937087
3722037088 // No check for duplicate because the check already happened in order
src/type.zig+3-1
......@@ -130,7 +130,9 @@ pub const Type = struct {
130130 @compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
131131 }
132132
133 pub fn fmt(ty: Type, module: *Module) std.fmt.Formatter(format2) {
133 pub const Formatter = std.fmt.Formatter(format2);
134
135 pub fn fmt(ty: Type, module: *Module) Formatter {
134136 return .{ .data = .{
135137 .ty = ty,
136138 .module = module,
test/cases/compile_errors/directly_embedding_opaque_type_in_struct_and_union.zig+2
......@@ -34,4 +34,6 @@ export fn d() void {
3434// :7:10: error: opaque types have unknown size and therefore cannot be directly embedded in unions
3535// :1:11: note: opaque declared here
3636// :19:22: error: cannot load opaque type 'tmp.O'
37// :1:11: note: opaque declared here
3738// :24:28: error: cannot load opaque type 'tmp.O'
39// :1:11: note: opaque declared here
test/cases/compile_errors/illegal_comparison_of_types.zig+1
......@@ -22,3 +22,4 @@ export fn entry2() usize {
2222//
2323// :2:14: error: operator == not allowed for type '[]u8'
2424// :9:16: error: operator == not allowed for type 'tmp.EnumWithData'
25// :4:22: note: union declared here
test/cases/compile_errors/int_from_enum_undefined.zig+1
......@@ -10,3 +10,4 @@ export fn a() void {
1010// target=native
1111//
1212// :5:22: error: cannot use @intFromEnum on empty enum 'tmp.a.E'
13// :2:15: note: enum declared here
test/cases/compile_errors/invalid_deref_on_switch_target.zig+1
......@@ -15,3 +15,4 @@ const Tile = enum {
1515// target=native
1616//
1717// :3:17: error: cannot dereference non-pointer type 'tmp.Tile'
18// :8:14: note: enum declared here
test/cases/compile_errors/invalid_inline_else_type.zig+1
......@@ -27,4 +27,5 @@ pub export fn entry3() void {
2727//
2828// :5:21: error: cannot enumerate values of type 'anyerror' for 'inline else'
2929// :13:21: error: cannot enumerate values of type 'tmp.E' for 'inline else'
30// :8:11: note: enum declared here
3031// :20:21: error: cannot enumerate values of type '*u32' for 'inline else'
test/cases/compile_errors/invalid_multiple_dereferences.zig+2
......@@ -17,4 +17,6 @@ pub const Box = struct {
1717// target=native
1818//
1919// :4:8: error: cannot dereference non-pointer type 'tmp.Box'
20// :11:17: note: struct declared here
2021// :9:14: error: cannot dereference non-pointer type 'tmp.Box'
22// :11:17: note: struct declared here
test/cases/compile_errors/non-const_variables_of_things_that_require_const_variables.zig+2
......@@ -44,6 +44,8 @@ export fn entry8() void {
4444// :14:9: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
4545// :18:9: error: variable of type '@TypeOf(null)' must be const or comptime
4646// :22:20: error: cannot load opaque type 'tmp.Opaque'
47// :29:16: note: opaque declared here
4748// :26:9: error: variable of type 'type' must be const or comptime
4849// :26:9: note: types are not available at runtime
4950// :31:12: error: non-extern variable with opaque type 'tmp.Opaque'
51// :29:16: note: opaque declared here