Point at impl self ty on type error involving Self

When encountering a type error involving a `Self` literal, point at the
self type of the enclosing `impl`.

CC #76086.
This commit is contained in:
Esteban Küber 2023-11-16 01:41:58 +00:00
parent 1be1e84872
commit a7e035ab89
2 changed files with 41 additions and 1 deletions

View File

@ -1738,6 +1738,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
// label pointing out the cause for the type coercion will be wrong
// as prior return coercions would not be relevant (#57664).
let fn_decl = if let (Some(expr), Some(blk_id)) = (expression, blk_id) {
self.explain_self_literal(fcx, &mut err, expr);
let pointing_at_return_type =
fcx.suggest_mismatched_types_on_tail(&mut err, expr, expected, found, blk_id);
if let (Some(cond_expr), true, false) = (
@ -1810,6 +1811,43 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
err
}
fn explain_self_literal(
&self,
fcx: &FnCtxt<'_, 'tcx>,
err: &mut Diagnostic,
expr: &'tcx hir::Expr<'tcx>,
) {
match expr.peel_drop_temps().kind {
hir::ExprKind::Struct(
hir::QPath::Resolved(
None,
hir::Path { res: hir::def::Res::SelfTyAlias { alias_to, .. }, .. },
),
..,
)
| hir::ExprKind::Call(
hir::Expr {
kind:
hir::ExprKind::Path(hir::QPath::Resolved(
None,
hir::Path { res: hir::def::Res::SelfTyAlias { alias_to, .. }, .. },
)),
..
},
..,
) => {
if let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Impl(hir::Impl { self_ty, .. }),
..
})) = fcx.tcx.hir().get_if_local(*alias_to)
{
err.span_label(self_ty.span, "this is the type of the `Self` literal");
}
}
_ => {}
}
}
/// Checks whether the return type is unsized via an obligation, which makes
/// sure we consider `dyn Trait: Sized` where clauses, which are trivially
/// false but technically valid for typeck.

View File

@ -24,7 +24,9 @@ error[E0308]: mismatched types
--> $DIR/struct-path-self-type-mismatch.rs:13:9
|
LL | impl<T> Foo<T> {
| - found type parameter
| - ------ this is the type of the `Self` literal
| |
| found type parameter
LL | fn new<U>(u: U) -> Foo<U> {
| - ------ expected `Foo<U>` because of return type
| |