Show type param definitions in type mismatch errors
Fixes #47319. Shows the type parameter definition(s) on type mismatch errors so the context is clearer. Pretty much changes the following: ``` LL | bar1(t); | ^ | | | expected enum `std::option::Option`, found type parameter `T` ``` into: ``` LL | fn foo1<T>(t: T) { | - this type parameter LL | bar1(t); | ^ | | | expected enum `std::option::Option`, found type parameter `T` ```
This commit is contained in:
parent
6a30ce639f
commit
036f182804
@ -1190,8 +1190,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// In some (most?) cases cause.body_id points to actual body, but in some cases
|
||||
// it's a actual definition. According to the comments (e.g. in
|
||||
// librustc_typeck/check/compare_method.rs:compare_predicate_entailment) the latter
|
||||
// is relied upon by some other code. This might (or might not) need cleanup.
|
||||
let body_owner_def_id = match self.tcx.hir().opt_local_def_id(cause.body_id) {
|
||||
Some(def_id) => def_id,
|
||||
None => self.tcx.hir().body_owner_def_id(hir::BodyId{hir_id: cause.body_id}),
|
||||
};
|
||||
self.check_and_note_conflicting_crates(diag, terr, span);
|
||||
self.tcx.note_and_explain_type_err(diag, terr, span);
|
||||
self.tcx.note_and_explain_type_err(diag, terr, span, body_owner_def_id);
|
||||
|
||||
// It reads better to have the error origin as the final
|
||||
// thing.
|
||||
|
@ -254,6 +254,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
db: &mut DiagnosticBuilder<'_>,
|
||||
err: &TypeError<'tcx>,
|
||||
sp: Span,
|
||||
body_owner_def_id: DefId,
|
||||
) {
|
||||
use self::TypeError::*;
|
||||
|
||||
@ -288,7 +289,16 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
);
|
||||
}
|
||||
},
|
||||
(ty::Param(_), ty::Param(_)) => {
|
||||
(ty::Param(expected), ty::Param(found)) => {
|
||||
let generics = self.generics_of(body_owner_def_id);
|
||||
db.span_label(
|
||||
self.def_span(generics.type_param(expected, self).def_id),
|
||||
"expected type parameter"
|
||||
);
|
||||
db.span_label(
|
||||
self.def_span(generics.type_param(found, self).def_id),
|
||||
"found type parameter"
|
||||
);
|
||||
db.note("a type parameter was expected, but a different one was found; \
|
||||
you might be missing a type parameter or trait bound");
|
||||
db.note("for more information, visit \
|
||||
@ -301,7 +311,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
(ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => {
|
||||
db.note("you might be missing a type parameter or trait bound");
|
||||
}
|
||||
(ty::Param(_), _) | (_, ty::Param(_)) => {
|
||||
(ty::Param(p), _) | (_, ty::Param(p)) => {
|
||||
let generics = self.generics_of(body_owner_def_id);
|
||||
db.span_label(
|
||||
self.def_span(generics.type_param(p, self).def_id),
|
||||
"this type parameter"
|
||||
);
|
||||
db.help("type parameters must be constrained to match other types");
|
||||
if self.sess.teach(&db.get_code().unwrap()) {
|
||||
db.help("given a type parameter `T` and a method `foo`:
|
||||
|
Loading…
x
Reference in New Issue
Block a user