Commit 51d67c7c8f
Changed files (9)
src/Sema.zig
@@ -2507,6 +2507,11 @@ pub fn fail(
args: anytype,
) CompileError {
const err_msg = try sema.errMsg(block, src, format, args);
+ inline for (args) |arg| {
+ if (@TypeOf(arg) == Type.Formatter) {
+ try addDeclaredHereNote(sema, err_msg, arg.data.ty);
+ }
+ }
return sema.failWithOwnedErrorMsg(block, err_msg);
}
@@ -5341,24 +5346,15 @@ fn failWithBadMemberAccess(
.Enum => "enum",
else => unreachable,
};
- const msg = msg: {
- const msg = blk: {
- if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {
- break :blk try sema.errMsg(block, field_src, "root struct of file '{}' has no member named '{}'", .{
- agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),
- });
- };
-
- break :blk try sema.errMsg(block, field_src, "{s} '{}' has no member named '{}'", .{
- kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),
- });
- };
-
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, agg_ty);
- break :msg msg;
+ if (agg_ty.getOwnerDeclOrNull(mod)) |some| if (mod.declIsRoot(some)) {
+ return sema.fail(block, field_src, "root struct of file '{}' has no member named '{}'", .{
+ agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),
+ });
};
- return sema.failWithOwnedErrorMsg(block, msg);
+
+ return sema.fail(block, field_src, "{s} '{}' has no member named '{}'", .{
+ kw_name, agg_ty.fmt(mod), field_name.fmt(&mod.intern_pool),
+ });
}
fn failWithBadStructFieldAccess(
@@ -8689,35 +8685,17 @@ fn zirEnumFromInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
if (try sema.intFitsInType(int_val, int_tag_ty, null)) {
return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
}
- const msg = msg: {
- const msg = try sema.errMsg(
- block,
- src,
- "int value '{}' out of range of non-exhaustive enum '{}'",
- .{ int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod) },
- );
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, dest_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, src, "int value '{}' out of range of non-exhaustive enum '{}'", .{
+ int_val.fmtValue(sema.typeOf(operand), mod), dest_ty.fmt(mod),
+ });
}
if (int_val.isUndef(mod)) {
return sema.failWithUseOfUndef(block, operand_src);
}
if (!(try sema.enumHasInt(dest_ty, int_val))) {
- const msg = msg: {
- const msg = try sema.errMsg(
- block,
- src,
- "enum '{}' has no tag with value '{}'",
- .{ dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod) },
- );
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, dest_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, src, "enum '{}' has no tag with value '{}'", .{
+ dest_ty.fmt(mod), int_val.fmtValue(sema.typeOf(operand), mod),
+ });
}
return Air.internedToRef((try mod.getCoerced(int_val, dest_ty)).toIntern());
}
@@ -9401,16 +9379,9 @@ fn funcCommon(
}
if (!param_ty.isValidParamType(mod)) {
const opaque_str = if (param_ty.zigTypeTag(mod) == .Opaque) "opaque " else "";
- const msg = msg: {
- const msg = try sema.errMsg(block, param_src, "parameter of {s}type '{}' not allowed", .{
- opaque_str, param_ty.fmt(mod),
- });
- errdefer msg.destroy(sema.gpa);
-
- try sema.addDeclaredHereNote(msg, param_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, param_src, "parameter of {s}type '{}' not allowed", .{
+ opaque_str, param_ty.fmt(mod),
+ });
}
if (!this_generic and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and !try sema.validateExternType(param_ty, .param_ty)) {
const msg = msg: {
@@ -9690,16 +9661,9 @@ fn finishFunc(
if (!return_type.isValidReturnType(mod)) {
const opaque_str = if (return_type.zigTypeTag(mod) == .Opaque) "opaque " else "";
- const msg = msg: {
- const msg = try sema.errMsg(block, ret_ty_src, "{s}return type '{}' not allowed", .{
- opaque_str, return_type.fmt(mod),
- });
- errdefer msg.destroy(gpa);
-
- try sema.addDeclaredHereNote(msg, return_type);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, ret_ty_src, "{s}return type '{}' not allowed", .{
+ opaque_str, return_type.fmt(mod),
+ });
}
if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(target, cc_resolved) and
!try sema.validateExternType(return_type, .ret_ty))
@@ -10848,15 +10812,9 @@ const SwitchProngAnalysis = struct {
else => unreachable,
};
const capture_src = raw_tag_capture_src.resolve(mod, mod.declPtr(block.src_decl), switch_node_offset, .none);
- const msg = msg: {
- const msg = try sema.errMsg(block, capture_src, "cannot capture tag of non-union type '{}'", .{
- operand_ty.fmt(mod),
- });
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, operand_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, capture_src, "cannot capture tag of non-union type '{}'", .{
+ operand_ty.fmt(mod),
+ });
}
assert(inline_case_capture != .none);
return inline_case_capture;
@@ -19824,13 +19782,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
const extra = sema.code.extraData(Zir.Inst.UnionInit, inst_data.payload_index).data;
const union_ty = try sema.resolveType(block, ty_src, extra.union_type);
if (union_ty.zigTypeTag(sema.mod) != .Union) {
- const msg = msg: {
- const msg = try sema.errMsg(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(sema.mod)});
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, union_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, ty_src, "expected union type, found '{}'", .{union_ty.fmt(sema.mod)});
}
const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{
.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
return sema.addStrLit(ip.stringToSlice(tag_name));
},
.Enum => operand_ty,
- .Union => operand_ty.unionTagType(mod) orelse {
- const msg = msg: {
- const msg = try sema.errMsg(block, src, "union '{}' is untagged", .{
- operand_ty.fmt(sema.mod),
- });
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, operand_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
- },
+ .Union => operand_ty.unionTagType(mod) orelse
+ return sema.fail(block, src, "union '{}' is untagged", .{operand_ty.fmt(sema.mod)}),
else => return sema.fail(block, operand_src, "expected enum or union; found '{}'", .{
operand_ty.fmt(mod),
}),
@@ -21567,16 +21510,9 @@ fn zirReify(
if (enum_tag_ty != .none) {
const tag_info = ip.indexToKey(enum_tag_ty).enum_type;
const enum_index = tag_info.nameIndex(ip, field_name) orelse {
- const msg = msg: {
- const msg = try sema.errMsg(block, src, "no field named '{}' in enum '{}'", .{
- field_name.fmt(ip),
- Type.fromInterned(enum_tag_ty).fmt(mod),
- });
- errdefer msg.destroy(gpa);
- try sema.addDeclaredHereNote(msg, Type.fromInterned(enum_tag_ty));
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, src, "no field named '{}' in enum '{}'", .{
+ field_name.fmt(ip), Type.fromInterned(enum_tag_ty).fmt(mod),
+ });
};
assert(explicit_tags_seen.len == tag_info.names.len);
// 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
break :disjoint true;
};
if (disjoint and dest_tag != .ErrorUnion) {
- const msg = msg: {
- const msg = try sema.errMsg(
- block,
- src,
- "error sets '{}' and '{}' have no common errors",
- .{ operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod) },
- );
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, operand_ty);
- try sema.addDeclaredHereNote(msg, dest_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, src, "error sets '{}' and '{}' have no common errors", .{
+ operand_ty.fmt(sema.mod), dest_ty.fmt(sema.mod),
+ });
}
if (maybe_operand_val) |val| {
@@ -22473,18 +22399,9 @@ fn zirErrorCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData
error_name = operand_val.err.name;
}
if (!Type.errorSetHasFieldIp(ip, dest_ty.toIntern(), error_name)) {
- const msg = msg: {
- const msg = try sema.errMsg(
- block,
- src,
- "'error.{}' not a member of error set '{}'",
- .{ error_name.fmt(ip), dest_ty.fmt(sema.mod) },
- );
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, dest_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, src, "'error.{}' not a member of error set '{}'", .{
+ error_name.fmt(ip), dest_ty.fmt(sema.mod),
+ });
}
}
@@ -23257,15 +23174,7 @@ fn bitOffsetOf(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!u6
try sema.resolveTypeLayout(ty);
switch (ty.zigTypeTag(mod)) {
.Struct => {},
- else => {
- const msg = msg: {
- const msg = try sema.errMsg(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)});
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
- },
+ else => return sema.fail(block, lhs_src, "expected struct type, found '{}'", .{ty.fmt(mod)}),
}
const field_index = if (ty.isTuple(mod)) blk: {
@@ -24708,23 +24617,9 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr
} orelse return sema.fail(block, ptr_src, "pointer value not based on parent struct", .{});
if (field.index != field_index) {
- const msg = msg: {
- const msg = try sema.errMsg(
- block,
- src,
- "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'",
- .{
- field_name.fmt(ip),
- field_index,
- field.index,
- parent_ty.fmt(sema.mod),
- },
- );
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, parent_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, src, "field '{}' has index '{d}' but pointer value is index '{d}' of struct '{}'", .{
+ field_name.fmt(ip), field_index, field.index, parent_ty.fmt(sema.mod),
+ });
}
return Air.internedToRef(field.base);
}
@@ -26916,15 +26811,9 @@ fn fieldVal(
switch (ip.indexToKey(child_type.toIntern())) {
.error_set_type => |error_set_type| blk: {
if (error_set_type.nameIndex(ip, field_name) != null) break :blk;
- const msg = msg: {
- const msg = try sema.errMsg(block, src, "no error named '{}' in '{}'", .{
- field_name.fmt(ip), child_type.fmt(mod),
- });
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, child_type);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, src, "no error named '{}' in '{}'", .{
+ field_name.fmt(ip), child_type.fmt(mod),
+ });
},
.inferred_error_set_type => {
return sema.fail(block, src, "TODO handle inferred error sets here", .{});
@@ -29072,18 +28961,9 @@ fn coerceExtra(
const val = try sema.resolveConstDefinedValue(block, .unneeded, inst, undefined);
const string = mod.intern_pool.indexToKey(val.toIntern()).enum_literal;
const field_index = dest_ty.enumFieldIndex(string, mod) orelse {
- const msg = msg: {
- const msg = try sema.errMsg(
- block,
- inst_src,
- "no field named '{}' in enum '{}'",
- .{ string.fmt(&mod.intern_pool), dest_ty.fmt(mod) },
- );
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, dest_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, inst_src, "no field named '{}' in enum '{}'", .{
+ string.fmt(&mod.intern_pool), dest_ty.fmt(mod),
+ });
};
return Air.internedToRef((try mod.enumValueFieldIndex(dest_ty, @intCast(field_index))).toIntern());
},
@@ -31718,15 +31598,9 @@ fn coerceEnumToUnion(
const enum_tag = try sema.coerce(block, tag_ty, inst, inst_src);
if (try sema.resolveDefinedValue(block, inst_src, enum_tag)) |val| {
const field_index = union_ty.unionTagFieldIndex(val, sema.mod) orelse {
- const msg = msg: {
- const msg = try sema.errMsg(block, inst_src, "union '{}' has no tag with value '{}'", .{
- union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod),
- });
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, union_ty);
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(block, msg);
+ return sema.fail(block, inst_src, "union '{}' has no tag with value '{}'", .{
+ union_ty.fmt(sema.mod), val.fmtValue(tag_ty, sema.mod),
+ });
};
const union_obj = mod.typeToUnion(union_ty).?;
@@ -37202,19 +37076,13 @@ fn semaUnionFields(mod: *Module, arena: Allocator, union_type: InternPool.Key.Un
if (explicit_tags_seen.len > 0) {
const tag_info = ip.indexToKey(union_type.tagTypePtr(ip).*).enum_type;
const enum_index = tag_info.nameIndex(ip, field_name) orelse {
- const msg = msg: {
- const ty_src = mod.fieldSrcLoc(union_type.decl, .{
- .index = field_i,
- .range = .name,
- }).lazy;
- const msg = try sema.errMsg(&block_scope, ty_src, "no field named '{}' in enum '{}'", .{
- field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(mod),
- });
- errdefer msg.destroy(sema.gpa);
- try sema.addDeclaredHereNote(msg, Type.fromInterned(union_type.tagTypePtr(ip).*));
- break :msg msg;
- };
- return sema.failWithOwnedErrorMsg(&block_scope, msg);
+ const ty_src = mod.fieldSrcLoc(union_type.decl, .{
+ .index = field_i,
+ .range = .name,
+ }).lazy;
+ return sema.fail(&block_scope, ty_src, "no field named '{}' in enum '{}'", .{
+ field_name.fmt(ip), Type.fromInterned(union_type.tagTypePtr(ip).*).fmt(mod),
+ });
};
// No check for duplicate because the check already happened in order
src/type.zig
@@ -130,7 +130,9 @@ pub const Type = struct {
@compileError("do not format types directly; use either ty.fmtDebug() or ty.fmt()");
}
- pub fn fmt(ty: Type, module: *Module) std.fmt.Formatter(format2) {
+ pub const Formatter = std.fmt.Formatter(format2);
+
+ pub fn fmt(ty: Type, module: *Module) Formatter {
return .{ .data = .{
.ty = ty,
.module = module,
test/cases/compile_errors/directly_embedding_opaque_type_in_struct_and_union.zig
@@ -34,4 +34,6 @@ export fn d() void {
// :7:10: error: opaque types have unknown size and therefore cannot be directly embedded in unions
// :1:11: note: opaque declared here
// :19:22: error: cannot load opaque type 'tmp.O'
+// :1:11: note: opaque declared here
// :24:28: error: cannot load opaque type 'tmp.O'
+// :1:11: note: opaque declared here
test/cases/compile_errors/illegal_comparison_of_types.zig
@@ -22,3 +22,4 @@ export fn entry2() usize {
//
// :2:14: error: operator == not allowed for type '[]u8'
// :9:16: error: operator == not allowed for type 'tmp.EnumWithData'
+// :4:22: note: union declared here
test/cases/compile_errors/int_from_enum_undefined.zig
@@ -10,3 +10,4 @@ export fn a() void {
// target=native
//
// :5:22: error: cannot use @intFromEnum on empty enum 'tmp.a.E'
+// :2:15: note: enum declared here
test/cases/compile_errors/invalid_deref_on_switch_target.zig
@@ -15,3 +15,4 @@ const Tile = enum {
// target=native
//
// :3:17: error: cannot dereference non-pointer type 'tmp.Tile'
+// :8:14: note: enum declared here
test/cases/compile_errors/invalid_inline_else_type.zig
@@ -27,4 +27,5 @@ pub export fn entry3() void {
//
// :5:21: error: cannot enumerate values of type 'anyerror' for 'inline else'
// :13:21: error: cannot enumerate values of type 'tmp.E' for 'inline else'
+// :8:11: note: enum declared here
// :20:21: error: cannot enumerate values of type '*u32' for 'inline else'
test/cases/compile_errors/invalid_multiple_dereferences.zig
@@ -17,4 +17,6 @@ pub const Box = struct {
// target=native
//
// :4:8: error: cannot dereference non-pointer type 'tmp.Box'
+// :11:17: note: struct declared here
// :9:14: error: cannot dereference non-pointer type 'tmp.Box'
+// :11:17: note: struct declared here
test/cases/compile_errors/non-const_variables_of_things_that_require_const_variables.zig
@@ -44,6 +44,8 @@ export fn entry8() void {
// :14:9: note: to modify this variable at runtime, it must be given an explicit fixed-size number type
// :18:9: error: variable of type '@TypeOf(null)' must be const or comptime
// :22:20: error: cannot load opaque type 'tmp.Opaque'
+// :29:16: note: opaque declared here
// :26:9: error: variable of type 'type' must be const or comptime
// :26:9: note: types are not available at runtime
// :31:12: error: non-extern variable with opaque type 'tmp.Opaque'
+// :29:16: note: opaque declared here