Skip to content

Commit 036f182

Browse files
committed
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` ```
1 parent 6a30ce6 commit 036f182

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

src/librustc/infer/error_reporting/mod.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -1190,8 +1190,16 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11901190
}
11911191
}
11921192

1193+
// In some (most?) cases cause.body_id points to actual body, but in some cases
1194+
// it's a actual definition. According to the comments (e.g. in
1195+
// librustc_typeck/check/compare_method.rs:compare_predicate_entailment) the latter
1196+
// is relied upon by some other code. This might (or might not) need cleanup.
1197+
let body_owner_def_id = match self.tcx.hir().opt_local_def_id(cause.body_id) {
1198+
Some(def_id) => def_id,
1199+
None => self.tcx.hir().body_owner_def_id(hir::BodyId{hir_id: cause.body_id}),
1200+
};
11931201
self.check_and_note_conflicting_crates(diag, terr, span);
1194-
self.tcx.note_and_explain_type_err(diag, terr, span);
1202+
self.tcx.note_and_explain_type_err(diag, terr, span, body_owner_def_id);
11951203

11961204
// It reads better to have the error origin as the final
11971205
// thing.

src/librustc/ty/error.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,7 @@ impl<'tcx> TyCtxt<'tcx> {
254254
db: &mut DiagnosticBuilder<'_>,
255255
err: &TypeError<'tcx>,
256256
sp: Span,
257+
body_owner_def_id: DefId,
257258
) {
258259
use self::TypeError::*;
259260

@@ -288,7 +289,16 @@ impl<'tcx> TyCtxt<'tcx> {
288289
);
289290
}
290291
},
291-
(ty::Param(_), ty::Param(_)) => {
292+
(ty::Param(expected), ty::Param(found)) => {
293+
let generics = self.generics_of(body_owner_def_id);
294+
db.span_label(
295+
self.def_span(generics.type_param(expected, self).def_id),
296+
"expected type parameter"
297+
);
298+
db.span_label(
299+
self.def_span(generics.type_param(found, self).def_id),
300+
"found type parameter"
301+
);
292302
db.note("a type parameter was expected, but a different one was found; \
293303
you might be missing a type parameter or trait bound");
294304
db.note("for more information, visit \
@@ -301,7 +311,12 @@ impl<'tcx> TyCtxt<'tcx> {
301311
(ty::Param(_), ty::Projection(_)) | (ty::Projection(_), ty::Param(_)) => {
302312
db.note("you might be missing a type parameter or trait bound");
303313
}
304-
(ty::Param(_), _) | (_, ty::Param(_)) => {
314+
(ty::Param(p), _) | (_, ty::Param(p)) => {
315+
let generics = self.generics_of(body_owner_def_id);
316+
db.span_label(
317+
self.def_span(generics.type_param(p, self).def_id),
318+
"this type parameter"
319+
);
305320
db.help("type parameters must be constrained to match other types");
306321
if self.sess.teach(&db.get_code().unwrap()) {
307322
db.help("given a type parameter `T` and a method `foo`:

0 commit comments

Comments
 (0)