@@ -203,13 +203,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
203
203
204
204
if !seen_spans. contains ( & move_span) {
205
205
if !closure {
206
- self . suggest_ref_or_clone (
207
- mpi,
208
- move_span,
209
- & mut err,
210
- & mut in_pattern,
211
- move_spans,
212
- ) ;
206
+ self . suggest_ref_or_clone ( mpi, & mut err, & mut in_pattern, move_spans) ;
213
207
}
214
208
215
209
let msg_opt = CapturedMessageOpt {
@@ -351,18 +345,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
351
345
fn suggest_ref_or_clone (
352
346
& self ,
353
347
mpi : MovePathIndex ,
354
- move_span : Span ,
355
348
err : & mut Diag < ' tcx > ,
356
349
in_pattern : & mut bool ,
357
350
move_spans : UseSpans < ' _ > ,
358
351
) {
352
+ let move_span = match move_spans {
353
+ UseSpans :: ClosureUse { capture_kind_span, .. } => capture_kind_span,
354
+ _ => move_spans. args_or_use ( ) ,
355
+ } ;
359
356
struct ExpressionFinder < ' hir > {
360
357
expr_span : Span ,
361
358
expr : Option < & ' hir hir:: Expr < ' hir > > ,
362
359
pat : Option < & ' hir hir:: Pat < ' hir > > ,
363
360
parent_pat : Option < & ' hir hir:: Pat < ' hir > > ,
361
+ hir : rustc_middle:: hir:: map:: Map < ' hir > ,
364
362
}
365
363
impl < ' hir > Visitor < ' hir > for ExpressionFinder < ' hir > {
364
+ type NestedFilter = OnlyBodies ;
365
+
366
+ fn nested_visit_map ( & mut self ) -> Self :: Map {
367
+ self . hir
368
+ }
369
+
366
370
fn visit_expr ( & mut self , e : & ' hir hir:: Expr < ' hir > ) {
367
371
if e. span == self . expr_span {
368
372
self . expr = Some ( e) ;
@@ -397,8 +401,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
397
401
let expr = hir. body ( body_id) . value ;
398
402
let place = & self . move_data . move_paths [ mpi] . place ;
399
403
let span = place. as_local ( ) . map ( |local| self . body . local_decls [ local] . source_info . span ) ;
400
- let mut finder =
401
- ExpressionFinder { expr_span : move_span, expr : None , pat : None , parent_pat : None } ;
404
+ let mut finder = ExpressionFinder {
405
+ expr_span : move_span,
406
+ expr : None ,
407
+ pat : None ,
408
+ parent_pat : None ,
409
+ hir,
410
+ } ;
402
411
finder. visit_expr ( expr) ;
403
412
if let Some ( span) = span
404
413
&& let Some ( expr) = finder. expr
@@ -479,12 +488,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
479
488
} else if let UseSpans :: ClosureUse {
480
489
closure_kind :
481
490
ClosureKind :: Coroutine ( CoroutineKind :: Desugared ( _, CoroutineSource :: Block ) ) ,
482
- args_span : _,
483
- capture_kind_span : _,
484
- path_span,
491
+ ..
485
492
} = move_spans
486
493
{
487
- self . suggest_cloning ( err, ty, expr, path_span ) ;
494
+ self . suggest_cloning ( err, ty, expr, None ) ;
488
495
} else if self . suggest_hoisting_call_outside_loop ( err, expr) {
489
496
// The place where the the type moves would be misleading to suggest clone.
490
497
// #121466
@@ -1233,6 +1240,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1233
1240
}
1234
1241
}
1235
1242
1243
+ fn in_move_closure ( & self , expr : & hir:: Expr < ' _ > ) -> bool {
1244
+ for ( _, node) in self . infcx . tcx . hir ( ) . parent_iter ( expr. hir_id ) {
1245
+ if let hir:: Node :: Expr ( hir:: Expr { kind : hir:: ExprKind :: Closure ( closure) , .. } ) = node
1246
+ && let hir:: CaptureBy :: Value { .. } = closure. capture_clause
1247
+ {
1248
+ // `move || x.clone()` will not work. FIXME: suggest `let y = x.clone(); move || y`
1249
+ return true ;
1250
+ }
1251
+ }
1252
+ false
1253
+ }
1254
+
1236
1255
fn suggest_cloning_inner (
1237
1256
& self ,
1238
1257
err : & mut Diag < ' _ > ,
@@ -1245,6 +1264,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
1245
1264
// See `tests/ui/moves/needs-clone-through-deref.rs`
1246
1265
return false ;
1247
1266
}
1267
+ if self . in_move_closure ( expr) {
1268
+ return false ;
1269
+ }
1248
1270
// Try to find predicates on *generic params* that would allow copying `ty`
1249
1271
let suggestion =
1250
1272
if let Some ( symbol) = tcx. hir ( ) . maybe_get_struct_pattern_shorthand_field ( expr) {
0 commit comments