Suggest replacing Self
with the right type on type error
When encountering a type error caused by the use of `Self`, suggest using the actual type name instead. ``` error[E0308]: mismatched types --> $DIR/struct-path-self-type-mismatch.rs:13:9 | LL | impl<T> Foo<T> { | - ------ 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 | | | expected type parameter LL | / Self { LL | | LL | | inner: u LL | | LL | | } | |_________^ expected `Foo<U>`, found `Foo<T>` | = note: expected struct `Foo<U>` found struct `Foo<T>` = note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters help: use the type name directly | LL | Foo::<U> { | ~~~~~~~~ ``` Fix #76086.
This commit is contained in:
parent
a7e035ab89
commit
d8456855f5
2 changed files with 27 additions and 4 deletions
|
@ -36,7 +36,9 @@
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use crate::FnCtxt;
|
use crate::FnCtxt;
|
||||||
use rustc_errors::{struct_span_err, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
|
use rustc_errors::{
|
||||||
|
struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
|
||||||
|
};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
|
@ -1738,7 +1740,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);
|
self.explain_self_literal(fcx, &mut err, expr, expected, found);
|
||||||
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) = (
|
||||||
|
@ -1816,12 +1818,14 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
fcx: &FnCtxt<'_, 'tcx>,
|
fcx: &FnCtxt<'_, 'tcx>,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
expr: &'tcx hir::Expr<'tcx>,
|
expr: &'tcx hir::Expr<'tcx>,
|
||||||
|
expected: Ty<'tcx>,
|
||||||
|
found: Ty<'tcx>,
|
||||||
) {
|
) {
|
||||||
match expr.peel_drop_temps().kind {
|
match expr.peel_drop_temps().kind {
|
||||||
hir::ExprKind::Struct(
|
hir::ExprKind::Struct(
|
||||||
hir::QPath::Resolved(
|
hir::QPath::Resolved(
|
||||||
None,
|
None,
|
||||||
hir::Path { res: hir::def::Res::SelfTyAlias { alias_to, .. }, .. },
|
hir::Path { res: hir::def::Res::SelfTyAlias { alias_to, .. }, span, .. },
|
||||||
),
|
),
|
||||||
..,
|
..,
|
||||||
)
|
)
|
||||||
|
@ -1830,7 +1834,11 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
kind:
|
kind:
|
||||||
hir::ExprKind::Path(hir::QPath::Resolved(
|
hir::ExprKind::Path(hir::QPath::Resolved(
|
||||||
None,
|
None,
|
||||||
hir::Path { res: hir::def::Res::SelfTyAlias { alias_to, .. }, .. },
|
hir::Path {
|
||||||
|
res: hir::def::Res::SelfTyAlias { alias_to, .. },
|
||||||
|
span,
|
||||||
|
..
|
||||||
|
},
|
||||||
)),
|
)),
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
|
@ -1843,6 +1851,17 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
|
||||||
{
|
{
|
||||||
err.span_label(self_ty.span, "this is the type of the `Self` literal");
|
err.span_label(self_ty.span, "this is the type of the `Self` literal");
|
||||||
}
|
}
|
||||||
|
if let ty::Adt(e_def, e_args) = expected.kind()
|
||||||
|
&& let ty::Adt(f_def, _f_args) = found.kind()
|
||||||
|
&& e_def == f_def
|
||||||
|
{
|
||||||
|
err.span_suggestion_verbose(
|
||||||
|
*span,
|
||||||
|
"use the type name directly",
|
||||||
|
fcx.tcx.value_path_str_with_args(*alias_to, e_args),
|
||||||
|
Applicability::MaybeIncorrect,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,10 @@ LL | | }
|
||||||
found struct `Foo<T>`
|
found struct `Foo<T>`
|
||||||
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
|
= note: a type parameter was expected, but a different one was found; you might be missing a type parameter or trait bound
|
||||||
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
= note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
|
||||||
|
help: use the type name directly
|
||||||
|
|
|
||||||
|
LL | Foo::<U> {
|
||||||
|
| ~~~~~~~~
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue