@@ -867,6 +867,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
867867 /// Compares two given types, eliding parts that are the same between them and highlighting
868868 /// relevant differences, and return two representation of those types for highlighted printing.
869869 fn cmp ( & self , t1 : Ty < ' tcx > , t2 : Ty < ' tcx > ) -> ( DiagnosticStyledString , DiagnosticStyledString ) {
870+ debug ! ( "cmp(t1={}, t1.kind={:?}, t2={}, t2.kind={:?})" , t1, t1. kind, t2, t2. kind) ;
871+
872+ // helper functions
870873 fn equals < ' tcx > ( a : Ty < ' tcx > , b : Ty < ' tcx > ) -> bool {
871874 match ( & a. kind , & b. kind ) {
872875 ( a, b) if * a == * b => true ,
@@ -902,6 +905,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
902905 s. push_normal ( ty. to_string ( ) ) ;
903906 }
904907
908+ // process starts here
905909 match ( & t1. kind , & t2. kind ) {
906910 ( & ty:: Adt ( def1, sub1) , & ty:: Adt ( def2, sub2) ) => {
907911 let sub_no_defaults_1 = self . strip_generic_default_params ( def1. did , sub1) ;
@@ -1052,12 +1056,47 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10521056 return values;
10531057 }
10541058
1055- // We couldn't find anything in common, highlight everything.
1056- // let x: Bar<Qux> = y::<Foo<Zar>>();
1057- (
1058- DiagnosticStyledString :: highlighted ( t1. to_string ( ) ) ,
1059- DiagnosticStyledString :: highlighted ( t2. to_string ( ) ) ,
1060- )
1059+ // We can't find anything in common, highlight relevant part of type path.
1060+ // let x: foo::bar::Baz<Qux> = y:<foo::bar::Bar<Zar>>();
1061+ // foo::bar::Baz<Qux>
1062+ // foo::bar::Bar<Zar>
1063+ // -------- this part of the path is different
1064+
1065+ let t1_str = t1. to_string ( ) ;
1066+ let t2_str = t2. to_string ( ) ;
1067+ let min_len = t1_str. len ( ) . min ( t2_str. len ( ) ) ;
1068+
1069+ const SEPARATOR : & str = "::" ;
1070+ let separator_len = SEPARATOR . len ( ) ;
1071+ let split_idx: usize =
1072+ t1_str. split ( SEPARATOR )
1073+ . zip ( t2_str. split ( SEPARATOR ) )
1074+ . take_while ( |( mod1_str, mod2_str) | mod1_str == mod2_str)
1075+ . map ( |( mod_str, _) | mod_str. len ( ) + separator_len)
1076+ . sum ( ) ;
1077+
1078+ debug ! ( "cmp: separator_len={}, split_idx={}, min_len={}" ,
1079+ separator_len, split_idx, min_len
1080+ ) ;
1081+
1082+ if split_idx >= min_len {
1083+ // paths are identical, highlight everything
1084+ (
1085+ DiagnosticStyledString :: highlighted ( t1_str) ,
1086+ DiagnosticStyledString :: highlighted ( t2_str)
1087+ )
1088+ } else {
1089+ let ( common, uniq1) = t1_str. split_at ( split_idx) ;
1090+ let ( _, uniq2) = t2_str. split_at ( split_idx) ;
1091+ debug ! ( "cmp: common={}, uniq1={}, uniq2={}" , common, uniq1, uniq2) ;
1092+
1093+ values. 0 . push_normal ( common) ;
1094+ values. 0 . push_highlighted ( uniq1) ;
1095+ values. 1 . push_normal ( common) ;
1096+ values. 1 . push_highlighted ( uniq2) ;
1097+
1098+ values
1099+ }
10611100 }
10621101 }
10631102
@@ -1120,6 +1159,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11201159 _ => { }
11211160 }
11221161
1162+ debug ! ( "note_type_err(diag={:?})" , diag) ;
11231163 let ( expected_found, exp_found, is_simple_error) = match values {
11241164 None => ( None , None , false ) ,
11251165 Some ( values) => {
@@ -1180,6 +1220,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11801220 diag. note_unsuccessfull_coercion ( found, expected) ;
11811221 }
11821222 ( _, false , _) => {
1223+ debug ! (
1224+ "note_type_err: exp_found={:?}, expected={:?} found={:?}" ,
1225+ exp_found, expected, found
1226+ ) ;
11831227 if let Some ( exp_found) = exp_found {
11841228 self . suggest_as_ref_where_appropriate ( span, & exp_found, diag) ;
11851229 }
0 commit comments