diff --git a/src/Sema.zig b/src/Sema.zig index f31e71047f..7cd8e0e635 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -30675,6 +30675,18 @@ fn coerceExtra( else => {}, } + const can_coerce_to = switch (dest_ty.zigTypeTag(zcu)) { + .noreturn, .@"opaque" => false, + else => true, + }; + + if (can_coerce_to) { + // undefined to anything. We do this after the big switch above so that + // special logic has a chance to run first, such as `*[N]T` to `[]T` which + // should initialize the length field of the slice. + if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty); + } + if (!opts.report_err) return error.NotCoercible; if (opts.is_ret and dest_ty.zigTypeTag(zcu) == .noreturn) { @@ -30692,15 +30704,14 @@ fn coerceExtra( return sema.failWithOwnedErrorMsg(block, msg); } - // undefined to anything. We do this after the big switch above so that - // special logic has a chance to run first, such as `*[N]T` to `[]T` which - // should initialize the length field of the slice. - if (maybe_inst_val) |val| if (val.toIntern() == .undef) return pt.undefRef(dest_ty); - const msg = msg: { const msg = try sema.errMsg(inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(pt), inst_ty.fmt(pt) }); errdefer msg.destroy(sema.gpa); + if (!can_coerce_to) { + try sema.errNote(inst_src, msg, "cannot coerce to '{}'", .{dest_ty.fmt(pt)}); + } + // E!T to T if (inst_ty.zigTypeTag(zcu) == .error_union and (try sema.coerceInMemoryAllowed(block, inst_ty.errorUnionPayload(zcu), dest_ty, false, target, dest_ty_src, inst_src, maybe_inst_val)) == .ok)