@@ -38,6 +38,7 @@ use std::fmt;
38
38
use syntax:: ast;
39
39
use syntax:: symbol:: { sym, kw} ;
40
40
use syntax_pos:: { DUMMY_SP , Span , ExpnKind , MultiSpan } ;
41
+ use rustc:: hir:: def_id:: LOCAL_CRATE ;
41
42
42
43
use rustc_error_codes:: * ;
43
44
@@ -799,6 +800,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
799
800
self . suggest_fn_call ( & obligation, & mut err, & trait_ref, points_at_arg) ;
800
801
self . suggest_remove_reference ( & obligation, & mut err, & trait_ref) ;
801
802
self . suggest_semicolon_removal ( & obligation, & mut err, span, & trait_ref) ;
803
+ self . note_version_mismatch ( & mut err, & trait_ref) ;
802
804
803
805
// Try to report a help message
804
806
if !trait_ref. has_infer_types ( ) &&
@@ -1050,6 +1052,43 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1050
1052
err. emit ( ) ;
1051
1053
}
1052
1054
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
+ }
1053
1092
fn suggest_restricting_param_bound (
1054
1093
& self ,
1055
1094
err : & mut DiagnosticBuilder < ' _ > ,
0 commit comments