@@ -226,6 +226,8 @@ pub trait ErrorReporting<'tcx> {
226
226
227
227
fn report_type_error ( & self , trace : TypeTrace < ' tcx > , terr : & ty:: TypeError < ' tcx > ) ;
228
228
229
+ fn check_and_note_conflicting_crates ( & self , terr : & ty:: TypeError < ' tcx > , sp : Span ) ;
230
+
229
231
fn report_and_explain_type_error ( & self ,
230
232
trace : TypeTrace < ' tcx > ,
231
233
terr : & ty:: TypeError < ' tcx > ) ;
@@ -484,13 +486,48 @@ impl<'a, 'tcx> ErrorReporting<'tcx> for InferCtxt<'a, 'tcx> {
484
486
expected_found_str,
485
487
terr) ;
486
488
489
+ self . check_and_note_conflicting_crates ( terr, trace. origin . span ( ) ) ;
490
+
487
491
match trace. origin {
488
492
infer:: MatchExpressionArm ( _, arm_span) =>
489
493
self . tcx . sess . span_note ( arm_span, "match arm with an incompatible type" ) ,
490
494
_ => ( )
491
495
}
492
496
}
493
497
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
+
494
531
fn report_and_explain_type_error ( & self ,
495
532
trace : TypeTrace < ' tcx > ,
496
533
terr : & ty:: TypeError < ' tcx > ) {
0 commit comments