@@ -1288,14 +1288,16 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
1288
1288
return false ;
1289
1289
}
1290
1290
// Try to find predicates on *generic params* that would allow copying `ty`
1291
- let suggestion =
1291
+ let mut suggestion =
1292
1292
if let Some ( symbol) = tcx. hir ( ) . maybe_get_struct_pattern_shorthand_field ( expr) {
1293
1293
format ! ( ": {symbol}.clone()" )
1294
1294
} else {
1295
1295
".clone()" . to_owned ( )
1296
1296
} ;
1297
1297
let mut sugg = Vec :: with_capacity ( 2 ) ;
1298
1298
let mut inner_expr = expr;
1299
+ let mut is_raw_ptr = false ;
1300
+ let typeck_result = self . infcx . tcx . typeck ( self . mir_def_id ( ) ) ;
1299
1301
// Remove uses of `&` and `*` when suggesting `.clone()`.
1300
1302
while let hir:: ExprKind :: AddrOf ( .., inner) | hir:: ExprKind :: Unary ( hir:: UnOp :: Deref , inner) =
1301
1303
& inner_expr. kind
@@ -1306,14 +1308,32 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
1306
1308
return false ;
1307
1309
}
1308
1310
inner_expr = inner;
1311
+ if let Some ( inner_type) = typeck_result. node_type_opt ( inner. hir_id ) {
1312
+ if matches ! ( inner_type. kind( ) , ty:: RawPtr ( ..) ) {
1313
+ is_raw_ptr = true ;
1314
+ break ;
1315
+ }
1316
+ }
1309
1317
}
1310
- if inner_expr. span . lo ( ) != expr. span . lo ( ) {
1318
+ // Cloning the raw pointer doesn't make sense in some cases and would cause a type mismatch error. (see #126863)
1319
+ if inner_expr. span . lo ( ) != expr. span . lo ( ) && !is_raw_ptr {
1320
+ // Remove "(*" or "(&"
1311
1321
sugg. push ( ( expr. span . with_hi ( inner_expr. span . lo ( ) ) , String :: new ( ) ) ) ;
1312
1322
}
1323
+ // Check whether `expr` is surrounded by parentheses or not.
1313
1324
let span = if inner_expr. span . hi ( ) != expr. span . hi ( ) {
1314
1325
// Account for `(*x)` to suggest `x.clone()`.
1315
- expr. span . with_lo ( inner_expr. span . hi ( ) )
1326
+ if is_raw_ptr {
1327
+ expr. span . shrink_to_hi ( )
1328
+ } else {
1329
+ // Remove the close parenthesis ")"
1330
+ expr. span . with_lo ( inner_expr. span . hi ( ) )
1331
+ }
1316
1332
} else {
1333
+ if is_raw_ptr {
1334
+ sugg. push ( ( expr. span . shrink_to_lo ( ) , "(" . to_string ( ) ) ) ;
1335
+ suggestion = ").clone()" . to_string ( ) ;
1336
+ }
1317
1337
expr. span . shrink_to_hi ( )
1318
1338
} ;
1319
1339
sugg. push ( ( span, suggestion) ) ;
0 commit comments