@@ -203,13 +203,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
203203
204204 if !seen_spans. contains ( & move_span) {
205205 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) ;
213207 }
214208
215209 let msg_opt = CapturedMessageOpt {
@@ -351,18 +345,28 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
351345 fn suggest_ref_or_clone (
352346 & self ,
353347 mpi : MovePathIndex ,
354- move_span : Span ,
355348 err : & mut Diag < ' tcx > ,
356349 in_pattern : & mut bool ,
357350 move_spans : UseSpans < ' _ > ,
358351 ) {
352+ let move_span = match move_spans {
353+ UseSpans :: ClosureUse { capture_kind_span, .. } => capture_kind_span,
354+ _ => move_spans. args_or_use ( ) ,
355+ } ;
359356 struct ExpressionFinder < ' hir > {
360357 expr_span : Span ,
361358 expr : Option < & ' hir hir:: Expr < ' hir > > ,
362359 pat : Option < & ' hir hir:: Pat < ' hir > > ,
363360 parent_pat : Option < & ' hir hir:: Pat < ' hir > > ,
361+ hir : rustc_middle:: hir:: map:: Map < ' hir > ,
364362 }
365363 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+
366370 fn visit_expr ( & mut self , e : & ' hir hir:: Expr < ' hir > ) {
367371 if e. span == self . expr_span {
368372 self . expr = Some ( e) ;
@@ -397,8 +401,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
397401 let expr = hir. body ( body_id) . value ;
398402 let place = & self . move_data . move_paths [ mpi] . place ;
399403 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+ } ;
402411 finder. visit_expr ( expr) ;
403412 if let Some ( span) = span
404413 && let Some ( expr) = finder. expr
@@ -479,12 +488,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
479488 } else if let UseSpans :: ClosureUse {
480489 closure_kind :
481490 ClosureKind :: Coroutine ( CoroutineKind :: Desugared ( _, CoroutineSource :: Block ) ) ,
482- args_span : _,
483- capture_kind_span : _,
484- path_span,
491+ ..
485492 } = move_spans
486493 {
487- self . suggest_cloning ( err, ty, expr, path_span ) ;
494+ self . suggest_cloning ( err, ty, expr, None ) ;
488495 } else if self . suggest_hoisting_call_outside_loop ( err, expr) {
489496 // The place where the the type moves would be misleading to suggest clone.
490497 // #121466
@@ -1233,6 +1240,18 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12331240 }
12341241 }
12351242
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+
12361255 fn suggest_cloning_inner (
12371256 & self ,
12381257 err : & mut Diag < ' _ > ,
@@ -1245,6 +1264,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
12451264 // See `tests/ui/moves/needs-clone-through-deref.rs`
12461265 return false ;
12471266 }
1267+ if self . in_move_closure ( expr) {
1268+ return false ;
1269+ }
12481270 // Try to find predicates on *generic params* that would allow copying `ty`
12491271 let suggestion =
12501272 if let Some ( symbol) = tcx. hir ( ) . maybe_get_struct_pattern_shorthand_field ( expr) {
0 commit comments