Skip to content

Commit a7e035a

Browse files
committed
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.
1 parent 1be1e84 commit a7e035a

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

compiler/rustc_hir_typeck/src/coercion.rs

+38
Original file line numberDiff line numberDiff line change
@@ -1738,6 +1738,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
17381738
// label pointing out the cause for the type coercion will be wrong
17391739
// as prior return coercions would not be relevant (#57664).
17401740
let fn_decl = if let (Some(expr), Some(blk_id)) = (expression, blk_id) {
1741+
self.explain_self_literal(fcx, &mut err, expr);
17411742
let pointing_at_return_type =
17421743
fcx.suggest_mismatched_types_on_tail(&mut err, expr, expected, found, blk_id);
17431744
if let (Some(cond_expr), true, false) = (
@@ -1810,6 +1811,43 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
18101811
err
18111812
}
18121813

1814+
fn explain_self_literal(
1815+
&self,
1816+
fcx: &FnCtxt<'_, 'tcx>,
1817+
err: &mut Diagnostic,
1818+
expr: &'tcx hir::Expr<'tcx>,
1819+
) {
1820+
match expr.peel_drop_temps().kind {
1821+
hir::ExprKind::Struct(
1822+
hir::QPath::Resolved(
1823+
None,
1824+
hir::Path { res: hir::def::Res::SelfTyAlias { alias_to, .. }, .. },
1825+
),
1826+
..,
1827+
)
1828+
| hir::ExprKind::Call(
1829+
hir::Expr {
1830+
kind:
1831+
hir::ExprKind::Path(hir::QPath::Resolved(
1832+
None,
1833+
hir::Path { res: hir::def::Res::SelfTyAlias { alias_to, .. }, .. },
1834+
)),
1835+
..
1836+
},
1837+
..,
1838+
) => {
1839+
if let Some(hir::Node::Item(hir::Item {
1840+
kind: hir::ItemKind::Impl(hir::Impl { self_ty, .. }),
1841+
..
1842+
})) = fcx.tcx.hir().get_if_local(*alias_to)
1843+
{
1844+
err.span_label(self_ty.span, "this is the type of the `Self` literal");
1845+
}
1846+
}
1847+
_ => {}
1848+
}
1849+
}
1850+
18131851
/// Checks whether the return type is unsized via an obligation, which makes
18141852
/// sure we consider `dyn Trait: Sized` where clauses, which are trivially
18151853
/// false but technically valid for typeck.

tests/ui/structs/struct-path-self-type-mismatch.stderr

+3-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ error[E0308]: mismatched types
2424
--> $DIR/struct-path-self-type-mismatch.rs:13:9
2525
|
2626
LL | impl<T> Foo<T> {
27-
| - found type parameter
27+
| - ------ this is the type of the `Self` literal
28+
| |
29+
| found type parameter
2830
LL | fn new<U>(u: U) -> Foo<U> {
2931
| - ------ expected `Foo<U>` because of return type
3032
| |

0 commit comments

Comments
 (0)