Skip to content

Commit 94e98bf

Browse files
Dedupe types when printing error messages
1 parent aa4332f commit 94e98bf

File tree

9 files changed

+254
-46
lines changed

9 files changed

+254
-46
lines changed

src/Air/print.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ const Writer = struct {
363363
}
364364

365365
fn writeType(w: *Writer, s: *std.Io.Writer, ty: Type) !void {
366-
return ty.print(s, w.pt);
366+
return ty.print(s, w.pt, null);
367367
}
368368

369369
fn writeTy(w: *Writer, s: *std.Io.Writer, inst: Air.Inst.Index) Error!void {

src/Sema.zig

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2447,19 +2447,6 @@ fn failWithStructInitNotSupported(sema: *Sema, block: *Block, src: LazySrcLoc, t
24472447
});
24482448
}
24492449

2450-
fn failWithErrorSetCodeMissing(
2451-
sema: *Sema,
2452-
block: *Block,
2453-
src: LazySrcLoc,
2454-
dest_err_set_ty: Type,
2455-
src_err_set_ty: Type,
2456-
) CompileError {
2457-
const pt = sema.pt;
2458-
return sema.fail(block, src, "expected type '{f}', found type '{f}'", .{
2459-
dest_err_set_ty.fmt(pt), src_err_set_ty.fmt(pt),
2460-
});
2461-
}
2462-
24632450
pub fn failWithIntegerOverflow(sema: *Sema, block: *Block, src: LazySrcLoc, int_ty: Type, val: Value, vector_index: ?usize) CompileError {
24642451
const pt = sema.pt;
24652452
return sema.failWithOwnedErrorMsg(block, msg: {
@@ -2619,6 +2606,26 @@ pub fn errMsg(
26192606
return Zcu.ErrorMsg.create(sema.gpa, src, format, args);
26202607
}
26212608

2609+
fn typeMismatchErrMsg(sema: *Sema, src: LazySrcLoc, expected: Type, found: Type) Allocator.Error!*Zcu.ErrorMsg {
2610+
const pt = sema.pt;
2611+
var cmp: Type.Comparison = try .init(&.{ expected, found }, pt);
2612+
defer cmp.deinit(pt);
2613+
2614+
const msg = try sema.errMsg(src, "expected type '{f}', found '{f}'", .{
2615+
cmp.fmtType(expected, pt),
2616+
cmp.fmtType(found, pt),
2617+
});
2618+
errdefer msg.destroy(sema.gpa);
2619+
2620+
for (cmp.type_dedupe_cache.keys(), cmp.type_dedupe_cache.values()) |ty, value| {
2621+
if (value == .dont_dedupe) continue;
2622+
const placeholder = value.dedupe;
2623+
try sema.errNote(src, msg, "{f} = {f}", .{ placeholder, ty.fmt(pt) });
2624+
}
2625+
2626+
return msg;
2627+
}
2628+
26222629
pub fn fail(
26232630
sema: *Sema,
26242631
block: *Block,
@@ -2635,6 +2642,14 @@ pub fn fail(
26352642
return sema.failWithOwnedErrorMsg(block, err_msg);
26362643
}
26372644

2645+
fn failWithTypeMismatch(sema: *Sema, block: *Block, src: LazySrcLoc, expected: Type, found: Type) CompileError {
2646+
const err_msg = try sema.typeMismatchErrMsg(src, expected, found);
2647+
errdefer err_msg.destroy(sema.gpa);
2648+
try addDeclaredHereNote(sema, err_msg, expected);
2649+
try addDeclaredHereNote(sema, err_msg, found);
2650+
return sema.failWithOwnedErrorMsg(block, err_msg);
2651+
}
2652+
26382653
pub fn failWithOwnedErrorMsg(sema: *Sema, block: ?*Block, err_msg: *Zcu.ErrorMsg) error{ AnalysisFail, OutOfMemory } {
26392654
@branchHint(.cold);
26402655
const gpa = sema.gpa;
@@ -22933,7 +22948,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
2293322948
const operand_is_vector = operand_ty.zigTypeTag(zcu) == .vector;
2293422949
const dest_is_vector = dest_ty.zigTypeTag(zcu) == .vector;
2293522950
if (operand_is_vector != dest_is_vector) {
22936-
return sema.fail(block, operand_src, "expected type '{f}', found '{f}'", .{ dest_ty.fmt(pt), operand_ty.fmt(pt) });
22951+
return sema.failWithTypeMismatch(block, operand_src, dest_ty, operand_ty);
2293722952
}
2293822953

2293922954
if (dest_scalar_ty.zigTypeTag(zcu) == .comptime_int) {
@@ -29167,7 +29182,7 @@ fn coerceExtra(
2916729182
}
2916829183

2916929184
const msg = msg: {
29170-
const msg = try sema.errMsg(inst_src, "expected type '{f}', found '{f}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) });
29185+
const msg = try sema.typeMismatchErrMsg(inst_src, dest_ty, inst_ty);
2917129186
errdefer msg.destroy(sema.gpa);
2917229187

2917329188
if (!can_coerce_to) {
@@ -30780,9 +30795,7 @@ fn coerceEnumToUnion(
3078030795

3078130796
const tag_ty = union_ty.unionTagType(zcu) orelse {
3078230797
const msg = msg: {
30783-
const msg = try sema.errMsg(inst_src, "expected type '{f}', found '{f}'", .{
30784-
union_ty.fmt(pt), inst_ty.fmt(pt),
30785-
});
30798+
const msg = try sema.typeMismatchErrMsg(inst_src, union_ty, inst_ty);
3078630799
errdefer msg.destroy(sema.gpa);
3078730800
try sema.errNote(union_ty_src, msg, "cannot coerce enum to untagged union", .{});
3078830801
try sema.addDeclaredHereNote(msg, union_ty);
@@ -30933,9 +30946,7 @@ fn coerceArrayLike(
3093330946
const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(zcu));
3093430947
if (dest_len != inst_len) {
3093530948
const msg = msg: {
30936-
const msg = try sema.errMsg(inst_src, "expected type '{f}', found '{f}'", .{
30937-
dest_ty.fmt(pt), inst_ty.fmt(pt),
30938-
});
30949+
const msg = try sema.typeMismatchErrMsg(inst_src, dest_ty, inst_ty);
3093930950
errdefer msg.destroy(sema.gpa);
3094030951
try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});
3094130952
try sema.errNote(inst_src, msg, "source has length {d}", .{inst_len});
@@ -31018,9 +31029,7 @@ fn coerceTupleToArray(
3101831029

3101931030
if (dest_len != inst_len) {
3102031031
const msg = msg: {
31021-
const msg = try sema.errMsg(inst_src, "expected type '{f}', found '{f}'", .{
31022-
dest_ty.fmt(pt), inst_ty.fmt(pt),
31023-
});
31032+
const msg = try sema.typeMismatchErrMsg(inst_src, dest_ty, inst_ty);
3102431033
errdefer msg.destroy(sema.gpa);
3102531034
try sema.errNote(dest_ty_src, msg, "destination has length {d}", .{dest_len});
3102631035
try sema.errNote(inst_src, msg, "source has length {d}", .{inst_len});
@@ -32719,12 +32728,12 @@ fn wrapErrorUnionSet(
3271932728
break :ok;
3272032729
},
3272132730
}
32722-
return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
32731+
return sema.failWithTypeMismatch(block, inst_src, dest_err_set_ty, inst_ty);
3272332732
},
3272432733
else => switch (ip.indexToKey(dest_err_set_ty.toIntern())) {
3272532734
.error_set_type => |error_set_type| ok: {
3272632735
if (error_set_type.nameIndex(ip, expected_name) != null) break :ok;
32727-
return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
32736+
return sema.failWithTypeMismatch(block, inst_src, dest_err_set_ty, inst_ty);
3272832737
},
3272932738
.inferred_error_set_type => |func_index| ok: {
3273032739
// We carefully do this in an order that avoids unnecessarily
@@ -32740,7 +32749,7 @@ fn wrapErrorUnionSet(
3274032749
},
3274132750
}
3274232751

32743-
return sema.failWithErrorSetCodeMissing(block, inst_src, dest_err_set_ty, inst_ty);
32752+
return sema.failWithTypeMismatch(block, inst_src, dest_err_set_ty, inst_ty);
3274432753
},
3274532754
else => unreachable,
3274632755
},

0 commit comments

Comments
 (0)