@@ -162,34 +162,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
162162
163163 let closure_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( local_def_id) ;
164164 if should_do_migration_analysis ( self . tcx , closure_hir_id) {
165- let need_migrations = self . compute_2229_migrations_first_pass (
166- closure_def_id,
167- span,
168- capture_clause,
169- body,
170- self . typeck_results . borrow ( ) . closure_min_captures . get ( & closure_def_id) ,
171- ) ;
172-
173- if !need_migrations. is_empty ( ) {
174- let need_migrations_hir_id =
175- need_migrations. iter ( ) . map ( |m| m. 0 ) . collect :: < Vec < _ > > ( ) ;
176-
177- let migrations_text =
178- migration_suggestion_for_2229 ( self . tcx , & need_migrations_hir_id) ;
179-
180- self . tcx . struct_span_lint_hir (
181- lint:: builtin:: DISJOINT_CAPTURE_DROP_REORDER ,
182- closure_hir_id,
183- span,
184- |lint| {
185- let mut diagnostics_builder = lint. build (
186- "drop order affected for closure because of `capture_disjoint_fields`" ,
187- ) ;
188- diagnostics_builder. note ( & migrations_text) ;
189- diagnostics_builder. emit ( ) ;
190- } ,
191- ) ;
192- }
165+ self . perform_2229_migration_anaysis ( closure_def_id, capture_clause, span, body) ;
193166 }
194167
195168 // We now fake capture information for all variables that are mentioned within the closure
@@ -555,6 +528,45 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
555528 typeck_results. closure_min_captures . insert ( closure_def_id, root_var_min_capture_list) ;
556529 }
557530
531+ /// Perform the migration analysis for RFC 2229, and emit lint
532+ /// `disjoint_capture_drop_reorder` if needed.
533+ fn perform_2229_migration_anaysis (
534+ & self ,
535+ closure_def_id : DefId ,
536+ capture_clause : hir:: CaptureBy ,
537+ span : Span ,
538+ body : & ' tcx hir:: Body < ' tcx > ,
539+ ) {
540+ let need_migrations = self . compute_2229_migrations_first_pass (
541+ closure_def_id,
542+ span,
543+ capture_clause,
544+ body,
545+ self . typeck_results . borrow ( ) . closure_min_captures . get ( & closure_def_id) ,
546+ ) ;
547+
548+ if !need_migrations. is_empty ( ) {
549+ let need_migrations_hir_id = need_migrations. iter ( ) . map ( |m| m. 0 ) . collect :: < Vec < _ > > ( ) ;
550+
551+ let migrations_text = migration_suggestion_for_2229 ( self . tcx , & need_migrations_hir_id) ;
552+
553+ let local_def_id = closure_def_id. expect_local ( ) ;
554+ let closure_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( local_def_id) ;
555+ self . tcx . struct_span_lint_hir (
556+ lint:: builtin:: DISJOINT_CAPTURE_DROP_REORDER ,
557+ closure_hir_id,
558+ span,
559+ |lint| {
560+ let mut diagnostics_builder = lint. build (
561+ "drop order affected for closure because of `capture_disjoint_fields`" ,
562+ ) ;
563+ diagnostics_builder. note ( & migrations_text) ;
564+ diagnostics_builder. emit ( ) ;
565+ } ,
566+ ) ;
567+ }
568+ }
569+
558570 /// Figures out the list of root variables (and their types) that aren't completely
559571 /// captured by the closure when `capture_disjoint_fields` is enabled and drop order of
560572 /// some path starting at that root variable **might** be affected.
@@ -617,17 +629,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
617629
618630 let is_moved = root_var_min_capture_list
619631 . iter ( )
620- . find ( |capture| matches ! ( capture. info. capture_kind, ty:: UpvarCapture :: ByValue ( _) ) )
621- . is_some ( ) ;
622-
623- // 1. If we capture more than one path starting at the root variabe then the root variable
624- // isn't being captured in its entirety
625- // 2. If we only capture one path starting at the root variable, it's still possible
626- // that it isn't the root variable completely.
627- if is_moved
628- && ( ( root_var_min_capture_list. len ( ) > 1 )
629- || ( root_var_min_capture_list[ 0 ] . place . projections . len ( ) > 0 ) )
630- {
632+ . any ( |capture| matches ! ( capture. info. capture_kind, ty:: UpvarCapture :: ByValue ( _) ) ) ;
633+
634+ let is_not_completely_captured =
635+ root_var_min_capture_list. iter ( ) . any ( |capture| capture. place . projections . len ( ) > 0 ) ;
636+
637+ if is_moved && is_not_completely_captured {
631638 need_migrations. push ( ( var_hir_id, ty) ) ;
632639 }
633640 }
0 commit comments