@@ -135,14 +135,17 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den
135135 . iterate_to_fixpoint ( tcx, body, None )
136136 . into_results_cursor ( body) ;
137137
138- let mut assignments = AssignmentResult :: find_dead_assignments ( & checked_places , & mut live , body) ;
138+ let typing_env = ty :: TypingEnv :: post_analysis ( tcx , body. source . def_id ( ) ) ;
139139
140- assignments. merge_guards ( & checked_places, body) ;
140+ let mut assignments =
141+ AssignmentResult :: find_dead_assignments ( tcx, typing_env, & checked_places, & mut live, body) ;
141142
142- let dead_captures = assignments. compute_dead_captures ( & checked_places , num_captures ) ;
143+ assignments. merge_guards ( ) ;
143144
144- assignments. report_fully_unused ( tcx, & checked_places, body) ;
145- assignments. report_unused_assignments ( tcx, def_id, & checked_places, body) ;
145+ let dead_captures = assignments. compute_dead_captures ( num_captures) ;
146+
147+ assignments. report_fully_unused ( ) ;
148+ assignments. report_unused_assignments ( ) ;
146149
147150 dead_captures
148151}
@@ -551,6 +554,7 @@ impl<'tcx> PlaceSet<'tcx> {
551554 }
552555 }
553556
557+ #[ inline]
554558 fn get ( & self , place : PlaceRef < ' tcx > ) -> Option < ( PlaceIndex , & ' tcx [ PlaceElem < ' tcx > ] ) > {
555559 if let Some ( index) = self . locals [ place. local ] {
556560 return Some ( ( index, place. projection ) ) ;
@@ -584,7 +588,11 @@ impl<'tcx> PlaceSet<'tcx> {
584588 }
585589}
586590
587- struct AssignmentResult {
591+ struct AssignmentResult < ' a , ' tcx > {
592+ tcx : TyCtxt < ' tcx > ,
593+ typing_env : ty:: TypingEnv < ' tcx > ,
594+ checked_places : & ' a PlaceSet < ' tcx > ,
595+ body : & ' a Body < ' tcx > ,
588596 /// Set of locals that are live at least once. This is used to report fully unused locals.
589597 ever_live : DenseBitSet < PlaceIndex > ,
590598 /// Set of locals that have a non-trivial drop. This is used to skip reporting unused
@@ -599,16 +607,18 @@ struct AssignmentResult {
599607 assignments : IndexVec < PlaceIndex , FxIndexMap < SourceInfo , Access > > ,
600608}
601609
602- impl AssignmentResult {
610+ impl < ' a , ' tcx > AssignmentResult < ' a , ' tcx > {
603611 /// Collect all assignments to checked locals.
604612 ///
605613 /// Assignments are collected, even if they are live. Dead assignments are reported, and live
606614 /// assignments are used to make diagnostics correct for match guards.
607- fn find_dead_assignments < ' tcx > (
608- checked_places : & PlaceSet < ' tcx > ,
615+ fn find_dead_assignments (
616+ tcx : TyCtxt < ' tcx > ,
617+ typing_env : ty:: TypingEnv < ' tcx > ,
618+ checked_places : & ' a PlaceSet < ' tcx > ,
609619 cursor : & mut ResultsCursor < ' _ , ' tcx , MaybeLivePlaces < ' _ , ' tcx > > ,
610- body : & Body < ' tcx > ,
611- ) -> AssignmentResult {
620+ body : & ' a Body < ' tcx > ,
621+ ) -> AssignmentResult < ' a , ' tcx > {
612622 let mut ever_live = DenseBitSet :: new_empty ( checked_places. len ( ) ) ;
613623 let mut ever_dropped = DenseBitSet :: new_empty ( checked_places. len ( ) ) ;
614624 let mut assignments = IndexVec :: < PlaceIndex , FxIndexMap < _ , _ > > :: from_elem (
@@ -718,7 +728,15 @@ impl AssignmentResult {
718728 }
719729 }
720730
721- AssignmentResult { ever_live, ever_dropped, assignments }
731+ AssignmentResult {
732+ tcx,
733+ typing_env,
734+ checked_places,
735+ ever_live,
736+ ever_dropped,
737+ assignments,
738+ body,
739+ }
722740 }
723741
724742 /// Match guards introduce a different local to freeze the guarded value as immutable.
@@ -732,16 +750,16 @@ impl AssignmentResult {
732750 /// _ => {}
733751 /// }
734752 ///
735- fn merge_guards < ' tcx > ( & mut self , checked_places : & PlaceSet < ' tcx > , body : & Body < ' _ > ) {
736- for ( index, place) in checked_places. iter ( ) {
753+ fn merge_guards ( & mut self ) {
754+ for ( index, place) in self . checked_places . iter ( ) {
737755 let local = place. local ;
738756 if let & LocalInfo :: User ( BindingForm :: RefForGuard ( arm_local) ) =
739- body. local_decls [ local] . local_info ( )
757+ self . body . local_decls [ local] . local_info ( )
740758 {
741759 debug_assert ! ( place. projection. is_empty( ) ) ;
742760
743761 // Local to use in the arm.
744- let Some ( ( arm_index, _proj) ) = checked_places. get ( arm_local. into ( ) ) else {
762+ let Some ( ( arm_index, _proj) ) = self . checked_places . get ( arm_local. into ( ) ) else {
745763 continue ;
746764 } ;
747765 debug_assert_ne ! ( index, arm_index) ;
@@ -776,14 +794,10 @@ impl AssignmentResult {
776794 }
777795
778796 /// Compute captures that are fully dead.
779- fn compute_dead_captures < ' tcx > (
780- & self ,
781- checked_places : & PlaceSet < ' tcx > ,
782- num_captures : usize ,
783- ) -> DenseBitSet < FieldIdx > {
797+ fn compute_dead_captures ( & self , num_captures : usize ) -> DenseBitSet < FieldIdx > {
784798 // Report to caller the set of dead captures.
785799 let mut dead_captures = DenseBitSet :: new_empty ( num_captures) ;
786- for ( index, place) in checked_places. iter ( ) {
800+ for ( index, place) in self . checked_places . iter ( ) {
787801 if self . ever_live . contains ( index) {
788802 continue ;
789803 }
@@ -804,16 +818,11 @@ impl AssignmentResult {
804818 }
805819
806820 /// Report fully unused locals, and forget the corresponding assignments.
807- fn report_fully_unused < ' tcx > (
808- & mut self ,
809- tcx : TyCtxt < ' tcx > ,
810- checked_places : & PlaceSet < ' tcx > ,
811- body : & Body < ' tcx > ,
812- ) {
813- let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
821+ fn report_fully_unused ( & mut self ) {
822+ let tcx = self . tcx ;
814823
815824 // First, report fully unused locals.
816- for ( index, place) in checked_places. iter ( ) {
825+ for ( index, place) in self . checked_places . iter ( ) {
817826 if self . ever_live . contains ( index) {
818827 continue ;
819828 }
@@ -824,21 +833,21 @@ impl AssignmentResult {
824833 }
825834
826835 let local = place. local ;
827- let decl = & body. local_decls [ local] ;
836+ let decl = & self . body . local_decls [ local] ;
828837
829838 if decl. from_compiler_desugaring ( ) {
830839 continue ;
831840 }
832841
833842 // Only report actual user-defined binding from now on.
834843 let LocalInfo :: User ( BindingForm :: Var ( binding) ) = decl. local_info ( ) else { continue } ;
835- let Some ( hir_id) = decl. source_info . scope . lint_root ( & body. source_scopes ) else {
844+ let Some ( hir_id) = decl. source_info . scope . lint_root ( & self . body . source_scopes ) else {
836845 continue ;
837846 } ;
838847
839848 let introductions = & binding. introductions ;
840849
841- let Some ( ( name, def_span) ) = checked_places. names [ index] else { continue } ;
850+ let Some ( ( name, def_span) ) = self . checked_places . names [ index] else { continue } ;
842851
843852 // #117284, when `ident_span` and `def_span` have different contexts
844853 // we can't provide a good suggestion, instead we pointed out the spans from macro
@@ -858,7 +867,7 @@ impl AssignmentResult {
858867 def_span,
859868 errors:: UnusedVariable {
860869 name,
861- string_interp : maybe_suggest_literal_matching_name ( body, name) ,
870+ string_interp : maybe_suggest_literal_matching_name ( self . body , name) ,
862871 sugg,
863872 } ,
864873 ) ;
@@ -889,11 +898,11 @@ impl AssignmentResult {
889898 // This is probably a drop-guard, so we do not issue a warning there.
890899 if maybe_drop_guard (
891900 tcx,
892- typing_env,
901+ self . typing_env ,
893902 index,
894903 & self . ever_dropped ,
895- checked_places,
896- body,
904+ self . checked_places ,
905+ self . body ,
897906 ) {
898907 statements. clear ( ) ;
899908 continue ;
@@ -945,7 +954,7 @@ impl AssignmentResult {
945954 spans,
946955 errors:: UnusedVariable {
947956 name,
948- string_interp : maybe_suggest_literal_matching_name ( body, name) ,
957+ string_interp : maybe_suggest_literal_matching_name ( self . body , name) ,
949958 sugg,
950959 } ,
951960 ) ;
@@ -954,25 +963,26 @@ impl AssignmentResult {
954963
955964 /// Second, report unused assignments that do not correspond to initialization.
956965 /// Initializations have been removed in the previous loop reporting unused variables.
957- fn report_unused_assignments < ' tcx > (
958- self ,
959- tcx : TyCtxt < ' tcx > ,
960- body_def_id : LocalDefId ,
961- checked_places : & PlaceSet < ' tcx > ,
962- body : & Body < ' tcx > ,
963- ) {
964- let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
966+ fn report_unused_assignments ( self ) {
967+ let tcx = self . tcx ;
965968
966969 for ( index, statements) in self . assignments . into_iter_enumerated ( ) {
967970 if statements. is_empty ( ) {
968971 continue ;
969972 }
970973
971- let Some ( ( name, decl_span) ) = checked_places. names [ index] else { continue } ;
974+ let Some ( ( name, decl_span) ) = self . checked_places . names [ index] else { continue } ;
972975
973976 // We have outstanding assignments and with non-trivial drop.
974977 // This is probably a drop-guard, so we do not issue a warning there.
975- if maybe_drop_guard ( tcx, typing_env, index, & self . ever_dropped , checked_places, body) {
978+ if maybe_drop_guard (
979+ tcx,
980+ self . typing_env ,
981+ index,
982+ & self . ever_dropped ,
983+ self . checked_places ,
984+ self . body ,
985+ ) {
976986 continue ;
977987 }
978988
@@ -984,18 +994,18 @@ impl AssignmentResult {
984994 }
985995
986996 // Report the dead assignment.
987- let Some ( hir_id) = source_info. scope . lint_root ( & body. source_scopes ) else {
997+ let Some ( hir_id) = source_info. scope . lint_root ( & self . body . source_scopes ) else {
988998 continue ;
989999 } ;
9901000
9911001 match kind {
9921002 AccessKind :: Assign => {
9931003 let suggestion = annotate_mut_binding_to_immutable_binding (
9941004 tcx,
995- checked_places. places [ index] ,
996- body_def_id ,
1005+ self . checked_places . places [ index] ,
1006+ self . body . source . def_id ( ) . expect_local ( ) ,
9971007 source_info. span ,
998- body,
1008+ self . body ,
9991009 ) ;
10001010 tcx. emit_node_span_lint (
10011011 lint:: builtin:: UNUSED_ASSIGNMENTS ,
0 commit comments