@@ -540,21 +540,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
540540 span : Span ,
541541 body : & ' tcx hir:: Body < ' tcx > ,
542542 ) {
543- let need_migrations_first_pass = self . compute_2229_migrations_first_pass (
543+ let need_migrations = self . compute_2229_migrations (
544544 closure_def_id,
545545 span,
546546 capture_clause,
547547 body,
548548 self . typeck_results . borrow ( ) . closure_min_captures . get ( & closure_def_id) ,
549549 ) ;
550550
551- let need_migrations = self . compute_2229_migrations_precise_pass (
552- closure_def_id,
553- span,
554- self . typeck_results . borrow ( ) . closure_min_captures . get ( & closure_def_id) ,
555- & need_migrations_first_pass,
556- ) ;
557-
558551 if !need_migrations. is_empty ( ) {
559552 let migrations_text = migration_suggestion_for_2229 ( self . tcx , & need_migrations) ;
560553
@@ -583,15 +576,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
583576 /// - It would have been moved into the closure when `capture_disjoint_fields` wasn't
584577 /// enabled, **and**
585578 /// - It wasn't completely captured by the closure, **and**
586- /// - The type of the root variable needs Drop.
587- fn compute_2229_migrations_first_pass (
579+ /// - One of the paths starting at this root variable, that is not captured needs Drop.
580+ fn compute_2229_migrations (
588581 & self ,
589582 closure_def_id : DefId ,
590583 closure_span : Span ,
591584 closure_clause : hir:: CaptureBy ,
592585 body : & ' tcx hir:: Body < ' tcx > ,
593586 min_captures : Option < & ty:: RootVariableMinCaptureList < ' tcx > > ,
594- ) -> Vec < ( hir:: HirId , Ty < ' tcx > ) > {
587+ ) -> Vec < hir:: HirId > {
595588 fn resolve_ty < T : TypeFoldable < ' tcx > > (
596589 fcx : & FnCtxt < ' _ , ' tcx > ,
597590 span : Span ,
@@ -627,64 +620,44 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
627620
628621 match closure_clause {
629622 // Only migrate if closure is a move closure
630- hir:: CaptureBy :: Value => need_migrations. push ( ( var_hir_id, ty ) ) ,
623+ hir:: CaptureBy :: Value => need_migrations. push ( var_hir_id) ,
631624
632625 hir:: CaptureBy :: Ref => { }
633626 }
634627
635628 continue ;
636629 } ;
637630
638- let is_moved = root_var_min_capture_list
631+ let projections_list = root_var_min_capture_list
639632 . iter ( )
640- . any ( |capture| matches ! ( capture. info. capture_kind, ty:: UpvarCapture :: ByValue ( _) ) ) ;
641-
642- let is_not_completely_captured =
643- root_var_min_capture_list. iter ( ) . any ( |capture| capture. place . projections . len ( ) > 0 ) ;
644-
645- if is_moved && is_not_completely_captured {
646- need_migrations. push ( ( var_hir_id, ty) ) ;
647- }
648- }
649-
650- need_migrations
651- }
652-
653- fn compute_2229_migrations_precise_pass (
654- & self ,
655- closure_def_id : DefId ,
656- closure_span : Span ,
657- min_captures : Option < & ty:: RootVariableMinCaptureList < ' tcx > > ,
658- need_migrations : & [ ( hir:: HirId , Ty < ' tcx > ) ] ,
659- ) -> Vec < hir:: HirId > {
660- // Need migrations -- second pass
661- let mut need_migrations_2 = Vec :: new ( ) ;
662-
663- for ( hir_id, ty) in need_migrations {
664- let projections_list = min_captures
665- . and_then ( |m| m. get ( hir_id) )
666- . into_iter ( )
667- . flatten ( )
668633 . filter_map ( |captured_place| match captured_place. info . capture_kind {
669634 // Only care about captures that are moved into the closure
670635 ty:: UpvarCapture :: ByValue ( ..) => {
671636 Some ( captured_place. place . projections . as_slice ( ) )
672637 }
673638 ty:: UpvarCapture :: ByRef ( ..) => None ,
674639 } )
675- . collect ( ) ;
640+ . collect :: < Vec < _ > > ( ) ;
676641
677- if self . has_significant_drop_outside_of_captures (
678- closure_def_id,
679- closure_span,
680- ty,
681- projections_list,
682- ) {
683- need_migrations_2. push ( * hir_id) ;
642+ let is_moved = !projections_list. is_empty ( ) ;
643+
644+ let is_not_completely_captured =
645+ root_var_min_capture_list. iter ( ) . any ( |capture| capture. place . projections . len ( ) > 0 ) ;
646+
647+ if is_moved
648+ && is_not_completely_captured
649+ && self . has_significant_drop_outside_of_captures (
650+ closure_def_id,
651+ closure_span,
652+ ty,
653+ projections_list,
654+ )
655+ {
656+ need_migrations. push ( var_hir_id) ;
684657 }
685658 }
686659
687- need_migrations_2
660+ need_migrations
688661 }
689662
690663 /// This is a helper function to `compute_2229_migrations_precise_pass`. Provided the type
@@ -822,21 +795,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
822795
823796 assert ! ( !is_completely_captured || ( captured_projs. len( ) == 1 ) ) ;
824797
825- if is_drop_defined_for_ty {
826- // If drop is implemented for this type then we need it to be fully captured, or
827- // it will require migration.
828- return !is_completely_captured;
829- }
830-
831798 if is_completely_captured {
832799 // The place is captured entirely, so doesn't matter if needs dtor, it will be drop
833800 // when the closure is dropped.
834801 return false ;
835802 }
836803
837- match base_path_ty. kind ( ) {
838- _ if captured_projs. is_empty ( ) => needs_drop ( base_path_ty) ,
804+ if is_drop_defined_for_ty {
805+ // If drop is implemented for this type then we need it to be fully captured,
806+ // which we know it is not because of the previous check. Therefore we need to
807+ // do migrate.
808+ return true ;
809+ }
810+
811+ if captured_projs. is_empty ( ) {
812+ return needs_drop ( base_path_ty) ;
813+ }
839814
815+ match base_path_ty. kind ( ) {
840816 // Observations:
841817 // - `captured_projs` is not empty. Therefore we can call
842818 // `captured_projs.first().unwrap()` safely.
0 commit comments