@@ -38,6 +38,7 @@ use std::fmt;
3838use syntax:: ast;
3939use syntax:: symbol:: { sym, kw} ;
4040use syntax_pos:: { DUMMY_SP , Span , ExpnKind , MultiSpan } ;
41+ use rustc:: hir:: def_id:: LOCAL_CRATE ;
4142
4243use rustc_error_codes:: * ;
4344
@@ -799,6 +800,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
799800 self . suggest_fn_call ( & obligation, & mut err, & trait_ref, points_at_arg) ;
800801 self . suggest_remove_reference ( & obligation, & mut err, & trait_ref) ;
801802 self . suggest_semicolon_removal ( & obligation, & mut err, span, & trait_ref) ;
803+ self . note_version_mismatch ( & mut err, & trait_ref) ;
802804
803805 // Try to report a help message
804806 if !trait_ref. has_infer_types ( ) &&
@@ -1050,6 +1052,43 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10501052 err. emit ( ) ;
10511053 }
10521054
1055+ /// If the `Self` type of the unsatisfied trait `trait_ref` implements a trait
1056+ /// with the same path as `trait_ref`, a help message about
1057+ /// a probable version mismatch is added to `err`
1058+ fn note_version_mismatch (
1059+ & self ,
1060+ err : & mut DiagnosticBuilder < ' _ > ,
1061+ trait_ref : & ty:: PolyTraitRef < ' tcx > ,
1062+ ) {
1063+ let get_trait_impl = |trait_def_id| {
1064+ let mut trait_impl = None ;
1065+ self . tcx . for_each_relevant_impl ( trait_def_id, trait_ref. self_ty ( ) , |impl_def_id| {
1066+ if trait_impl. is_none ( ) {
1067+ trait_impl = Some ( impl_def_id) ;
1068+ }
1069+ } ) ;
1070+ trait_impl
1071+ } ;
1072+ let required_trait_path = self . tcx . def_path_str ( trait_ref. def_id ( ) ) ;
1073+ let all_traits = self . tcx . all_traits ( LOCAL_CRATE ) ;
1074+ let traits_with_same_path: std:: collections:: BTreeSet < _ > = all_traits
1075+ . iter ( )
1076+ . filter ( |trait_def_id| * * trait_def_id != trait_ref. def_id ( ) )
1077+ . filter ( |trait_def_id| self . tcx . def_path_str ( * * trait_def_id) == required_trait_path)
1078+ . collect ( ) ;
1079+ for trait_with_same_path in traits_with_same_path {
1080+ if let Some ( impl_def_id) = get_trait_impl ( * trait_with_same_path) {
1081+ let impl_span = self . tcx . def_span ( impl_def_id) ;
1082+ err. span_help ( impl_span, "Trait impl with same name found" ) ;
1083+ let trait_crate = self . tcx . crate_name ( trait_with_same_path. krate ) ;
1084+ let crate_msg = format ! (
1085+ "Perhaps two different versions of crate `{}` are being used?" ,
1086+ trait_crate
1087+ ) ;
1088+ err. note ( & crate_msg) ;
1089+ }
1090+ }
1091+ }
10531092 fn suggest_restricting_param_bound (
10541093 & self ,
10551094 err : & mut DiagnosticBuilder < ' _ > ,
0 commit comments