diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2015-09-08 19:48:56 +0530 |
|---|---|---|
| committer | Manish Goregaokar <manishsmail@gmail.com> | 2015-09-08 19:48:56 +0530 |
| commit | 8b16eb832596d305f7da3f88c64aa35762fcba1e (patch) | |
| tree | d649fbf37c86225a76757ff295eb1534616cf64c | |
| parent | 7bf626a68045be1d1a4fac9a635113bb7775b6bb (diff) | |
| download | rust-8b16eb832596d305f7da3f88c64aa35762fcba1e.tar.gz rust-8b16eb832596d305f7da3f88c64aa35762fcba1e.zip | |
Add note for when a type error comes from similarly named objects from two different crate of the same name (#22750)
| -rw-r--r-- | src/librustc/middle/infer/error_reporting.rs | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index 8197ccf4be7..67357ab239f 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -226,6 +226,8 @@ pub trait ErrorReporting<'tcx> { fn report_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::TypeError<'tcx>); + fn check_and_note_conflicting_crates(&self, terr: &ty::TypeError<'tcx>, sp: Span); + fn report_and_explain_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::TypeError<'tcx>); @@ -484,6 +486,8 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { expected_found_str, terr); + self.check_and_note_conflicting_crates(terr, trace.origin.span()); + match trace.origin { infer::MatchExpressionArm(_, arm_span) => self.tcx.sess.span_note(arm_span, "match arm with an incompatible type"), @@ -491,6 +495,39 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> { } } + /// Adds a note if the types come from similarly named crates + fn check_and_note_conflicting_crates(&self, terr: &ty::TypeError<'tcx>, sp: Span) { + match *terr { + ty::TypeError::Sorts(ref exp_found) => { + // if they are both "path types", there's a chance of ambiguity + // due to different versions of the same crate + match (&exp_found.expected.sty, &exp_found.found.sty) { + (&ty::TyEnum(ref exp_adt, _), &ty::TyEnum(ref found_adt, _)) | + (&ty::TyStruct(ref exp_adt, _), &ty::TyStruct(ref found_adt, _)) | + (&ty::TyEnum(ref exp_adt, _), &ty::TyStruct(ref found_adt, _)) | + (&ty::TyStruct(ref exp_adt, _), &ty::TyEnum(ref found_adt, _)) => { + // Only external crates, if either is from a local + // module we could have false positives + if exp_adt.did.is_local() || found_adt.did.is_local() { + return + } + let exp_path = self.tcx.with_path(exp_adt.did, + |p| p.collect::<Vec<_>>()); + let found_path = self.tcx.with_path(exp_adt.did, + |p| p.collect::<Vec<_>>()); + if exp_path == found_path { + self.tcx.sess.span_note(sp, &format!("Perhaps two different versions \ + of crate `{}` are being used?", + exp_path[0])); + } + }, + _ => () + } + } + _ => () // FIXME(Manishearth) handle traits and stuff + } + } + fn report_and_explain_type_error(&self, trace: TypeTrace<'tcx>, terr: &ty::TypeError<'tcx>) { |
