@@ -1087,7 +1087,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1087
1087
/// ```ignore (illustrative)
1088
1088
/// opt.map(|param| { takes_ref(param) });
1089
1089
/// ```
1090
- fn can_use_as_ref ( & self , expr : & hir:: Expr < ' _ > ) -> Option < ( Span , & ' static str , String ) > {
1090
+ fn can_use_as_ref ( & self , expr : & hir:: Expr < ' _ > ) -> Option < ( Vec < ( Span , String ) > , & ' static str ) > {
1091
1091
let hir:: ExprKind :: Path ( hir:: QPath :: Resolved ( _, ref path) ) = expr. kind else {
1092
1092
return None ;
1093
1093
} ;
@@ -1133,12 +1133,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1133
1133
}
1134
1134
_ => false ,
1135
1135
} ;
1136
- match ( is_as_ref_able, self . sess ( ) . source_map ( ) . span_to_snippet ( method_path. ident . span ) ) {
1137
- ( true , Ok ( src) ) => {
1138
- let suggestion = format ! ( "as_ref().{}" , src) ;
1139
- Some ( ( method_path. ident . span , "consider using `as_ref` instead" , suggestion) )
1140
- }
1141
- _ => None ,
1136
+ if is_as_ref_able {
1137
+ Some ( (
1138
+ vec ! [ ( method_path. ident. span. shrink_to_lo( ) , "as_ref()." . to_string( ) ) ] ,
1139
+ "consider using `as_ref` instead" ,
1140
+ ) )
1141
+ } else {
1142
+ None
1142
1143
}
1143
1144
}
1144
1145
@@ -1223,8 +1224,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1223
1224
checked_ty : Ty < ' tcx > ,
1224
1225
expected : Ty < ' tcx > ,
1225
1226
) -> Option < (
1226
- Span ,
1227
- String ,
1227
+ Vec < ( Span , String ) > ,
1228
1228
String ,
1229
1229
Applicability ,
1230
1230
bool , /* verbose */
@@ -1254,30 +1254,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1254
1254
&& let Ok ( src) = sm. span_to_snippet ( sp)
1255
1255
&& replace_prefix ( & src, "b\" " , "\" " ) . is_some ( )
1256
1256
{
1257
- let pos = sp. lo ( ) + BytePos ( 1 ) ;
1258
- return Some ( (
1259
- sp. with_hi ( pos) ,
1260
- "consider removing the leading `b`" . to_string ( ) ,
1261
- String :: new ( ) ,
1262
- Applicability :: MachineApplicable ,
1263
- true ,
1264
- false ,
1265
- ) ) ;
1266
- }
1267
- }
1257
+ let pos = sp. lo ( ) + BytePos ( 1 ) ;
1258
+ return Some ( (
1259
+ vec ! [ ( sp. with_hi( pos) , String :: new( ) ) ] ,
1260
+ "consider removing the leading `b`" . to_string ( ) ,
1261
+ Applicability :: MachineApplicable ,
1262
+ true ,
1263
+ false ,
1264
+ ) ) ;
1265
+ }
1266
+ }
1268
1267
( & ty:: Array ( arr, _) | & ty:: Slice ( arr) , & ty:: Str ) if arr == self . tcx . types . u8 => {
1269
1268
if let hir:: ExprKind :: Lit ( _) = expr. kind
1270
1269
&& let Ok ( src) = sm. span_to_snippet ( sp)
1271
1270
&& replace_prefix ( & src, "\" " , "b\" " ) . is_some ( )
1272
1271
{
1273
- return Some ( (
1274
- sp. shrink_to_lo ( ) ,
1275
- "consider adding a leading `b`" . to_string ( ) ,
1276
- "b" . to_string ( ) ,
1277
- Applicability :: MachineApplicable ,
1278
- true ,
1279
- false ,
1280
- ) ) ;
1272
+ return Some ( (
1273
+ vec ! [ ( sp. shrink_to_lo( ) , "b" . to_string( ) ) ] ,
1274
+ "consider adding a leading `b`" . to_string ( ) ,
1275
+ Applicability :: MachineApplicable ,
1276
+ true ,
1277
+ false ,
1278
+ ) ) ;
1281
1279
}
1282
1280
}
1283
1281
_ => { }
@@ -1320,14 +1318,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1320
1318
}
1321
1319
1322
1320
if let hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , ref inner) = expr. kind
1323
- && let Some ( 1 ) = self . deref_steps ( expected, checked_ty) {
1321
+ && let Some ( 1 ) = self . deref_steps ( expected, checked_ty)
1322
+ {
1324
1323
// We have `*&T`, check if what was expected was `&T`.
1325
1324
// If so, we may want to suggest removing a `*`.
1326
1325
sugg_sp = sugg_sp. with_hi ( inner. span . lo ( ) ) ;
1327
1326
return Some ( (
1328
- sugg_sp,
1327
+ vec ! [ ( sugg_sp, String :: new ( ) ) ] ,
1329
1328
"consider removing deref here" . to_string ( ) ,
1330
- "" . to_string ( ) ,
1331
1329
Applicability :: MachineApplicable ,
1332
1330
true ,
1333
1331
false ,
@@ -1342,13 +1340,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1342
1340
_ => false ,
1343
1341
} ;
1344
1342
1345
- if let Some ( sugg) = self . can_use_as_ref ( expr) {
1343
+ if let Some ( ( sugg, msg ) ) = self . can_use_as_ref ( expr) {
1346
1344
return Some ( (
1347
- sugg. 0 ,
1348
- sugg. 1 . to_string ( ) ,
1349
- sugg. 2 ,
1345
+ sugg,
1346
+ msg. to_string ( ) ,
1350
1347
Applicability :: MachineApplicable ,
1351
- false ,
1348
+ true ,
1352
1349
false ,
1353
1350
) ) ;
1354
1351
}
@@ -1369,16 +1366,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1369
1366
}
1370
1367
}
1371
1368
1372
- let ( sp, sugg_expr, verbose) = if needs_parens {
1373
- let src = sm. span_to_snippet ( sugg_sp) . ok ( ) ?;
1374
- ( sp, format ! ( "({src})" ) , false )
1369
+ let sugg = mutability. ref_prefix_str ( ) ;
1370
+ let ( sugg, verbose) = if needs_parens {
1371
+ (
1372
+ vec ! [
1373
+ ( sp. shrink_to_lo( ) , format!( "{prefix}{sugg}(" ) ) ,
1374
+ ( sp. shrink_to_hi( ) , ")" . to_string( ) ) ,
1375
+ ] ,
1376
+ false ,
1377
+ )
1375
1378
} else {
1376
- ( sp. shrink_to_lo ( ) , "" . to_string ( ) , true )
1379
+ ( vec ! [ ( sp. shrink_to_lo( ) , format! ( "{prefix}{sugg}" ) ) ] , true )
1377
1380
} ;
1378
1381
return Some ( (
1379
- sp ,
1382
+ sugg ,
1380
1383
format ! ( "consider {}borrowing here" , mutability. mutably_str( ) ) ,
1381
- format ! ( "{prefix}{}{sugg_expr}" , mutability. ref_prefix_str( ) ) ,
1382
1384
Applicability :: MachineApplicable ,
1383
1385
verbose,
1384
1386
false ,
@@ -1404,23 +1406,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1404
1406
&& sm. is_span_accessible ( call_span)
1405
1407
{
1406
1408
return Some ( (
1407
- sp. with_hi ( call_span. lo ( ) ) ,
1409
+ vec ! [ ( sp. with_hi( call_span. lo( ) ) , String :: new ( ) ) ] ,
1408
1410
"consider removing the borrow" . to_string ( ) ,
1409
- String :: new ( ) ,
1410
1411
Applicability :: MachineApplicable ,
1411
1412
true ,
1412
- true
1413
+ true ,
1413
1414
) ) ;
1414
1415
}
1415
1416
return None ;
1416
1417
}
1417
- if sp. contains ( expr. span )
1418
- && sm. is_span_accessible ( expr. span )
1419
- {
1418
+ if sp. contains ( expr. span ) && sm. is_span_accessible ( expr. span ) {
1420
1419
return Some ( (
1421
- sp. with_hi ( expr. span . lo ( ) ) ,
1420
+ vec ! [ ( sp. with_hi( expr. span. lo( ) ) , String :: new ( ) ) ] ,
1422
1421
"consider removing the borrow" . to_string ( ) ,
1423
- String :: new ( ) ,
1424
1422
Applicability :: MachineApplicable ,
1425
1423
true ,
1426
1424
true ,
@@ -1444,23 +1442,30 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1444
1442
1445
1443
let suggestion = replace_prefix ( & src, old_prefix, & new_prefix) . map ( |_| {
1446
1444
// skip `&` or `&mut ` if both mutabilities are mutable
1447
- let lo = sp. lo ( ) + BytePos ( min ( old_prefix. len ( ) , mutbl_b. ref_prefix_str ( ) . len ( ) ) as _ ) ;
1445
+ let lo = sp. lo ( )
1446
+ + BytePos ( min ( old_prefix. len ( ) , mutbl_b. ref_prefix_str ( ) . len ( ) ) as _ ) ;
1448
1447
// skip `&` or `&mut `
1449
1448
let hi = sp. lo ( ) + BytePos ( old_prefix. len ( ) as _ ) ;
1450
1449
let sp = sp. with_lo ( lo) . with_hi ( hi) ;
1451
1450
1452
1451
(
1453
1452
sp,
1454
- format ! ( "{}{derefs}" , if mutbl_a != mutbl_b { mutbl_b. prefix_str( ) } else { "" } ) ,
1455
- if mutbl_b <= mutbl_a { Applicability :: MachineApplicable } else { Applicability :: MaybeIncorrect }
1453
+ format ! (
1454
+ "{}{derefs}" ,
1455
+ if mutbl_a != mutbl_b { mutbl_b. prefix_str( ) } else { "" }
1456
+ ) ,
1457
+ if mutbl_b <= mutbl_a {
1458
+ Applicability :: MachineApplicable
1459
+ } else {
1460
+ Applicability :: MaybeIncorrect
1461
+ } ,
1456
1462
)
1457
1463
} ) ;
1458
1464
1459
1465
if let Some ( ( span, src, applicability) ) = suggestion {
1460
1466
return Some ( (
1461
- span,
1467
+ vec ! [ ( span, src ) ] ,
1462
1468
"consider dereferencing" . to_string ( ) ,
1463
- src,
1464
1469
applicability,
1465
1470
true ,
1466
1471
false ,
@@ -1489,9 +1494,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1489
1494
// If we've reached our target type with just removing `&`, then just print now.
1490
1495
if steps == 0 && !remove. trim ( ) . is_empty ( ) {
1491
1496
return Some ( (
1492
- prefix_span,
1497
+ vec ! [ ( prefix_span, String :: new ( ) ) ] ,
1493
1498
format ! ( "consider removing the `{}`" , remove. trim( ) ) ,
1494
- String :: new ( ) ,
1495
1499
// Do not remove `&&` to get to bool, because it might be something like
1496
1500
// { a } && b, which we have a separate fixup suggestion that is more
1497
1501
// likely correct...
@@ -1557,9 +1561,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
1557
1561
}
1558
1562
1559
1563
return Some ( (
1560
- span,
1564
+ vec ! [ ( span, suggestion ) ] ,
1561
1565
message,
1562
- suggestion,
1563
1566
Applicability :: MachineApplicable ,
1564
1567
true ,
1565
1568
false ,
0 commit comments