Skip to content

Commit 8b16eb8

Browse files
committed
Add note for when a type error comes from similarly named objects from two different crate of the same name (rust-lang#22750)
1 parent 7bf626a commit 8b16eb8

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

src/librustc/middle/infer/error_reporting.rs

+37
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ pub trait ErrorReporting<'tcx> {
226226

227227
fn report_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::TypeError<'tcx>);
228228

229+
fn check_and_note_conflicting_crates(&self, terr: &ty::TypeError<'tcx>, sp: Span);
230+
229231
fn report_and_explain_type_error(&self,
230232
trace: TypeTrace<'tcx>,
231233
terr: &ty::TypeError<'tcx>);
@@ -484,13 +486,48 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
484486
expected_found_str,
485487
terr);
486488

489+
self.check_and_note_conflicting_crates(terr, trace.origin.span());
490+
487491
match trace.origin {
488492
infer::MatchExpressionArm(_, arm_span) =>
489493
self.tcx.sess.span_note(arm_span, "match arm with an incompatible type"),
490494
_ => ()
491495
}
492496
}
493497

498+
/// Adds a note if the types come from similarly named crates
499+
fn check_and_note_conflicting_crates(&self, terr: &ty::TypeError<'tcx>, sp: Span) {
500+
match *terr {
501+
ty::TypeError::Sorts(ref exp_found) => {
502+
// if they are both "path types", there's a chance of ambiguity
503+
// due to different versions of the same crate
504+
match (&exp_found.expected.sty, &exp_found.found.sty) {
505+
(&ty::TyEnum(ref exp_adt, _), &ty::TyEnum(ref found_adt, _)) |
506+
(&ty::TyStruct(ref exp_adt, _), &ty::TyStruct(ref found_adt, _)) |
507+
(&ty::TyEnum(ref exp_adt, _), &ty::TyStruct(ref found_adt, _)) |
508+
(&ty::TyStruct(ref exp_adt, _), &ty::TyEnum(ref found_adt, _)) => {
509+
// Only external crates, if either is from a local
510+
// module we could have false positives
511+
if exp_adt.did.is_local() || found_adt.did.is_local() {
512+
return
513+
}
514+
let exp_path = self.tcx.with_path(exp_adt.did,
515+
|p| p.collect::<Vec<_>>());
516+
let found_path = self.tcx.with_path(exp_adt.did,
517+
|p| p.collect::<Vec<_>>());
518+
if exp_path == found_path {
519+
self.tcx.sess.span_note(sp, &format!("Perhaps two different versions \
520+
of crate `{}` are being used?",
521+
exp_path[0]));
522+
}
523+
},
524+
_ => ()
525+
}
526+
}
527+
_ => () // FIXME(Manishearth) handle traits and stuff
528+
}
529+
}
530+
494531
fn report_and_explain_type_error(&self,
495532
trace: TypeTrace<'tcx>,
496533
terr: &ty::TypeError<'tcx>) {

0 commit comments

Comments
 (0)