@@ -1181,37 +1181,54 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
11811181 debug ! ( "cmp(t1={}, t1.kind={:?}, t2={}, t2.kind={:?})" , t1, t1. kind( ) , t2, t2. kind( ) ) ;
11821182
11831183 // helper functions
1184- fn equals < ' tcx > ( a : Ty < ' tcx > , b : Ty < ' tcx > ) -> bool {
1185- match ( a. kind ( ) , b. kind ( ) ) {
1186- ( a, b) if * a == * b => true ,
1187- ( & ty:: Int ( _) , & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) )
1188- | (
1189- & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) ,
1190- & ty:: Int ( _) | & ty:: Infer ( ty:: InferTy :: IntVar ( _) ) ,
1191- )
1192- | ( & ty:: Float ( _) , & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) )
1193- | (
1194- & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) ,
1195- & ty:: Float ( _) | & ty:: Infer ( ty:: InferTy :: FloatVar ( _) ) ,
1196- ) => true ,
1197- _ => false ,
1184+ let recurse = |t1, t2, values : & mut ( DiagnosticStyledString , DiagnosticStyledString ) | {
1185+ let ( x1, x2) = self . cmp ( t1, t2) ;
1186+ ( values. 0 ) . 0 . extend ( x1. 0 ) ;
1187+ ( values. 1 ) . 0 . extend ( x2. 0 ) ;
1188+ } ;
1189+
1190+ fn fmt_region < ' tcx > ( region : ty:: Region < ' tcx > ) -> String {
1191+ let mut r = region. to_string ( ) ;
1192+ if r == "'_" {
1193+ r. clear ( ) ;
1194+ } else {
1195+ r. push ( ' ' ) ;
11981196 }
1197+ format ! ( "&{r}" )
11991198 }
12001199
1201- fn push_ty_ref < ' tcx > (
1200+ fn push_ref < ' tcx > (
12021201 region : ty:: Region < ' tcx > ,
1203- ty : Ty < ' tcx > ,
12041202 mutbl : hir:: Mutability ,
12051203 s : & mut DiagnosticStyledString ,
12061204 ) {
1207- let mut r = region. to_string ( ) ;
1208- if r == "'_" {
1209- r. clear ( ) ;
1205+ s. push_highlighted ( fmt_region ( region) ) ;
1206+ s. push_highlighted ( mutbl. prefix_str ( ) ) ;
1207+ }
1208+
1209+ fn cmp_ty_refs < ' tcx > (
1210+ r1 : ty:: Region < ' tcx > ,
1211+ mut1 : hir:: Mutability ,
1212+ r2 : ty:: Region < ' tcx > ,
1213+ mut2 : hir:: Mutability ,
1214+ ss : & mut ( DiagnosticStyledString , DiagnosticStyledString ) ,
1215+ ) {
1216+ let ( r1, r2) = ( fmt_region ( r1) , fmt_region ( r2) ) ;
1217+ if r1 != r2 {
1218+ ss. 0 . push_highlighted ( r1) ;
1219+ ss. 1 . push_highlighted ( r2) ;
12101220 } else {
1211- r. push ( ' ' ) ;
1221+ ss. 0 . push_normal ( r1) ;
1222+ ss. 1 . push_normal ( r2) ;
1223+ }
1224+
1225+ if mut1 != mut2 {
1226+ ss. 0 . push_highlighted ( mut1. prefix_str ( ) ) ;
1227+ ss. 1 . push_highlighted ( mut2. prefix_str ( ) ) ;
1228+ } else {
1229+ ss. 0 . push_normal ( mut1. prefix_str ( ) ) ;
1230+ ss. 1 . push_normal ( mut2. prefix_str ( ) ) ;
12121231 }
1213- s. push_highlighted ( format ! ( "&{}{}" , r, mutbl. prefix_str( ) ) ) ;
1214- s. push_normal ( ty. to_string ( ) ) ;
12151232 }
12161233
12171234 // process starts here
@@ -1310,9 +1327,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
13101327 values. 0 . push_normal ( "_" ) ;
13111328 values. 1 . push_normal ( "_" ) ;
13121329 } else {
1313- let ( x1, x2) = self . cmp ( ta1, ta2) ;
1314- ( values. 0 ) . 0 . extend ( x1. 0 ) ;
1315- ( values. 1 ) . 0 . extend ( x2. 0 ) ;
1330+ recurse ( ta1, ta2, & mut values) ;
13161331 }
13171332 self . push_comma ( & mut values. 0 , & mut values. 1 , len, i) ;
13181333 }
@@ -1418,27 +1433,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
14181433 }
14191434 }
14201435
1421- // When finding T != &T, highlight only the borrow
1422- ( & ty:: Ref ( r1, ref_ty1, mutbl1) , _ ) if equals ( ref_ty1 , t2 ) => {
1436+ // When finding `& T != &T`, compare the references, then recurse into pointee type
1437+ ( & ty:: Ref ( r1, ref_ty1, mutbl1) , & ty :: Ref ( r2 , ref_ty2 , mutbl2 ) ) => {
14231438 let mut values = ( DiagnosticStyledString :: new ( ) , DiagnosticStyledString :: new ( ) ) ;
1424- push_ty_ref ( r1, ref_ty1 , mutbl1 , & mut values. 0 ) ;
1425- values . 1 . push_normal ( t2 . to_string ( ) ) ;
1439+ cmp_ty_refs ( r1, mutbl1 , r2 , mutbl2 , & mut values) ;
1440+ recurse ( ref_ty1 , ref_ty2 , & mut values ) ;
14261441 values
14271442 }
1428- ( _, & ty:: Ref ( r2, ref_ty2, mutbl2) ) if equals ( t1, ref_ty2) => {
1443+ // When finding T != &T, highlight the borrow
1444+ ( & ty:: Ref ( r1, ref_ty1, mutbl1) , _) => {
14291445 let mut values = ( DiagnosticStyledString :: new ( ) , DiagnosticStyledString :: new ( ) ) ;
1430- values. 0 . push_normal ( t1 . to_string ( ) ) ;
1431- push_ty_ref ( r2 , ref_ty2 , mutbl2 , & mut values. 1 ) ;
1446+ push_ref ( r1 , mutbl1 , & mut values. 0 ) ;
1447+ recurse ( ref_ty1 , t2 , & mut values) ;
14321448 values
14331449 }
1434-
1435- // When encountering &T != &mut T, highlight only the borrow
1436- ( & ty:: Ref ( r1, ref_ty1, mutbl1) , & ty:: Ref ( r2, ref_ty2, mutbl2) )
1437- if equals ( ref_ty1, ref_ty2) =>
1438- {
1450+ ( _, & ty:: Ref ( r2, ref_ty2, mutbl2) ) => {
14391451 let mut values = ( DiagnosticStyledString :: new ( ) , DiagnosticStyledString :: new ( ) ) ;
1440- push_ty_ref ( r1 , ref_ty1 , mutbl1 , & mut values. 0 ) ;
1441- push_ty_ref ( r2 , ref_ty2, mutbl2 , & mut values. 1 ) ;
1452+ push_ref ( r2 , mutbl2 , & mut values. 1 ) ;
1453+ recurse ( t1 , ref_ty2, & mut values) ;
14421454 values
14431455 }
14441456
@@ -1448,9 +1460,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
14481460 ( DiagnosticStyledString :: normal ( "(" ) , DiagnosticStyledString :: normal ( "(" ) ) ;
14491461 let len = args1. len ( ) ;
14501462 for ( i, ( left, right) ) in args1. iter ( ) . zip ( args2) . enumerate ( ) {
1451- let ( x1, x2) = self . cmp ( left, right) ;
1452- ( values. 0 ) . 0 . extend ( x1. 0 ) ;
1453- ( values. 1 ) . 0 . extend ( x2. 0 ) ;
1463+ recurse ( left, right, & mut values) ;
14541464 self . push_comma ( & mut values. 0 , & mut values. 1 , len, i) ;
14551465 }
14561466 if len == 1 {
0 commit comments