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:
parent
1be1e84872
commit
a7e035ab89
2 changed files with 41 additions and 1 deletions
|
@ -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
|
// label pointing out the cause for the type coercion will be wrong
|
||||||
// as prior return coercions would not be relevant (#57664).
|
// as prior return coercions would not be relevant (#57664).
|
||||||
let fn_decl = if let (Some(expr), Some(blk_id)) = (expression, blk_id) {
|
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 =
|
let pointing_at_return_type =
|
||||||
fcx.suggest_mismatched_types_on_tail(&mut err, expr, expected, found, blk_id);
|
fcx.suggest_mismatched_types_on_tail(&mut err, expr, expected, found, blk_id);
|
||||||
if let (Some(cond_expr), true, false) = (
|
if let (Some(cond_expr), true, false) = (
|
||||||
|
@ -1810,6 +1811,43 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
err
|
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
|
/// Checks whether the return type is unsized via an obligation, which makes
|
||||||
/// sure we consider `dyn Trait: Sized` where clauses, which are trivially
|
/// sure we consider `dyn Trait: Sized` where clauses, which are trivially
|
||||||
/// false but technically valid for typeck.
|
/// false but technically valid for typeck.
|
||||||
|
|
|
@ -24,7 +24,9 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/struct-path-self-type-mismatch.rs:13:9
|
--> $DIR/struct-path-self-type-mismatch.rs:13:9
|
||||||
|
|
|
|
||||||
LL | impl<T> Foo<T> {
|
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> {
|
LL | fn new<U>(u: U) -> Foo<U> {
|
||||||
| - ------ expected `Foo<U>` because of return type
|
| - ------ expected `Foo<U>` because of return type
|
||||||
| |
|
| |
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue