@@ -867,6 +867,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
867
867
/// Compares two given types, eliding parts that are the same between them and highlighting
868
868
/// relevant differences, and return two representation of those types for highlighted printing.
869
869
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
870
873
fn equals < ' tcx > ( a : Ty < ' tcx > , b : Ty < ' tcx > ) -> bool {
871
874
match ( & a. kind , & b. kind ) {
872
875
( a, b) if * a == * b => true ,
@@ -902,6 +905,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
902
905
s. push_normal ( ty. to_string ( ) ) ;
903
906
}
904
907
908
+ // process starts here
905
909
match ( & t1. kind , & t2. kind ) {
906
910
( & ty:: Adt ( def1, sub1) , & ty:: Adt ( def2, sub2) ) => {
907
911
let sub_no_defaults_1 = self . strip_generic_default_params ( def1. did , sub1) ;
@@ -1052,12 +1056,47 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1052
1056
return values;
1053
1057
}
1054
1058
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
+ }
1061
1100
}
1062
1101
}
1063
1102
@@ -1120,6 +1159,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1120
1159
_ => { }
1121
1160
}
1122
1161
1162
+ debug ! ( "note_type_err(diag={:?})" , diag) ;
1123
1163
let ( expected_found, exp_found, is_simple_error) = match values {
1124
1164
None => ( None , None , false ) ,
1125
1165
Some ( values) => {
@@ -1180,6 +1220,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1180
1220
diag. note_unsuccessfull_coercion ( found, expected) ;
1181
1221
}
1182
1222
( _, false , _) => {
1223
+ debug ! (
1224
+ "note_type_err: exp_found={:?}, expected={:?} found={:?}" ,
1225
+ exp_found, expected, found
1226
+ ) ;
1183
1227
if let Some ( exp_found) = exp_found {
1184
1228
self . suggest_as_ref_where_appropriate ( span, & exp_found, diag) ;
1185
1229
}
0 commit comments