@@ -1181,37 +1181,54 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1181
1181
debug ! ( "cmp(t1={}, t1.kind={:?}, t2={}, t2.kind={:?})" , t1, t1. kind( ) , t2, t2. kind( ) ) ;
1182
1182
1183
1183
// 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 ( ' ' ) ;
1198
1196
}
1197
+ format ! ( "&{r}" )
1199
1198
}
1200
1199
1201
- fn push_ty_ref < ' tcx > (
1200
+ fn push_ref < ' tcx > (
1202
1201
region : ty:: Region < ' tcx > ,
1203
- ty : Ty < ' tcx > ,
1204
1202
mutbl : hir:: Mutability ,
1205
1203
s : & mut DiagnosticStyledString ,
1206
1204
) {
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) ;
1210
1220
} 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 ( ) ) ;
1212
1231
}
1213
- s. push_highlighted ( format ! ( "&{}{}" , r, mutbl. prefix_str( ) ) ) ;
1214
- s. push_normal ( ty. to_string ( ) ) ;
1215
1232
}
1216
1233
1217
1234
// process starts here
@@ -1310,9 +1327,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1310
1327
values. 0 . push_normal ( "_" ) ;
1311
1328
values. 1 . push_normal ( "_" ) ;
1312
1329
} 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) ;
1316
1331
}
1317
1332
self . push_comma ( & mut values. 0 , & mut values. 1 , len, i) ;
1318
1333
}
@@ -1418,27 +1433,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1418
1433
}
1419
1434
}
1420
1435
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 ) ) => {
1423
1438
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 ) ;
1426
1441
values
1427
1442
}
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) , _) => {
1429
1445
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) ;
1432
1448
values
1433
1449
}
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) ) => {
1439
1451
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) ;
1442
1454
values
1443
1455
}
1444
1456
@@ -1448,9 +1460,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
1448
1460
( DiagnosticStyledString :: normal ( "(" ) , DiagnosticStyledString :: normal ( "(" ) ) ;
1449
1461
let len = args1. len ( ) ;
1450
1462
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) ;
1454
1464
self . push_comma ( & mut values. 0 , & mut values. 1 , len, i) ;
1455
1465
}
1456
1466
if len == 1 {
0 commit comments