@@ -134,14 +134,17 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den
134
134
. iterate_to_fixpoint ( tcx, body, None )
135
135
. into_results_cursor ( body) ;
136
136
137
- let mut assignments = AssignmentResult :: find_dead_assignments ( & checked_places , & mut live , body) ;
137
+ let typing_env = ty :: TypingEnv :: post_analysis ( tcx , body. source . def_id ( ) ) ;
138
138
139
- assignments. merge_guards ( & checked_places, body) ;
139
+ let mut assignments =
140
+ AssignmentResult :: find_dead_assignments ( tcx, typing_env, & checked_places, & mut live, body) ;
140
141
141
- let dead_captures = assignments. compute_dead_captures ( & checked_places , num_captures ) ;
142
+ assignments. merge_guards ( ) ;
142
143
143
- assignments. report_fully_unused ( tcx, & checked_places, body) ;
144
- assignments. report_unused_assignments ( tcx, def_id, & checked_places, body) ;
144
+ let dead_captures = assignments. compute_dead_captures ( num_captures) ;
145
+
146
+ assignments. report_fully_unused ( ) ;
147
+ assignments. report_unused_assignments ( ) ;
145
148
146
149
dead_captures
147
150
}
@@ -550,6 +553,7 @@ impl<'tcx> PlaceSet<'tcx> {
550
553
}
551
554
}
552
555
556
+ #[ inline]
553
557
fn get ( & self , place : PlaceRef < ' tcx > ) -> Option < ( PlaceIndex , & ' tcx [ PlaceElem < ' tcx > ] ) > {
554
558
if let Some ( index) = self . locals [ place. local ] {
555
559
return Some ( ( index, place. projection ) ) ;
@@ -583,7 +587,11 @@ impl<'tcx> PlaceSet<'tcx> {
583
587
}
584
588
}
585
589
586
- struct AssignmentResult {
590
+ struct AssignmentResult < ' a , ' tcx > {
591
+ tcx : TyCtxt < ' tcx > ,
592
+ typing_env : ty:: TypingEnv < ' tcx > ,
593
+ checked_places : & ' a PlaceSet < ' tcx > ,
594
+ body : & ' a Body < ' tcx > ,
587
595
/// Set of locals that are live at least once. This is used to report fully unused locals.
588
596
ever_live : DenseBitSet < PlaceIndex > ,
589
597
/// Set of locals that have a non-trivial drop. This is used to skip reporting unused
@@ -598,16 +606,18 @@ struct AssignmentResult {
598
606
assignments : IndexVec < PlaceIndex , FxIndexMap < SourceInfo , Access > > ,
599
607
}
600
608
601
- impl AssignmentResult {
609
+ impl < ' a , ' tcx > AssignmentResult < ' a , ' tcx > {
602
610
/// Collect all assignments to checked locals.
603
611
///
604
612
/// Assignments are collected, even if they are live. Dead assignments are reported, and live
605
613
/// assignments are used to make diagnostics correct for match guards.
606
- fn find_dead_assignments < ' tcx > (
607
- checked_places : & PlaceSet < ' tcx > ,
614
+ fn find_dead_assignments (
615
+ tcx : TyCtxt < ' tcx > ,
616
+ typing_env : ty:: TypingEnv < ' tcx > ,
617
+ checked_places : & ' a PlaceSet < ' tcx > ,
608
618
cursor : & mut ResultsCursor < ' _ , ' tcx , MaybeLivePlaces < ' _ , ' tcx > > ,
609
- body : & Body < ' tcx > ,
610
- ) -> AssignmentResult {
619
+ body : & ' a Body < ' tcx > ,
620
+ ) -> AssignmentResult < ' a , ' tcx > {
611
621
let mut ever_live = DenseBitSet :: new_empty ( checked_places. len ( ) ) ;
612
622
let mut ever_dropped = DenseBitSet :: new_empty ( checked_places. len ( ) ) ;
613
623
let mut assignments = IndexVec :: < PlaceIndex , FxIndexMap < _ , _ > > :: from_elem (
@@ -717,7 +727,15 @@ impl AssignmentResult {
717
727
}
718
728
}
719
729
720
- AssignmentResult { ever_live, ever_dropped, assignments }
730
+ AssignmentResult {
731
+ tcx,
732
+ typing_env,
733
+ checked_places,
734
+ ever_live,
735
+ ever_dropped,
736
+ assignments,
737
+ body,
738
+ }
721
739
}
722
740
723
741
/// Match guards introduce a different local to freeze the guarded value as immutable.
@@ -731,16 +749,16 @@ impl AssignmentResult {
731
749
/// _ => {}
732
750
/// }
733
751
///
734
- fn merge_guards < ' tcx > ( & mut self , checked_places : & PlaceSet < ' tcx > , body : & Body < ' _ > ) {
735
- for ( index, place) in checked_places. iter ( ) {
752
+ fn merge_guards ( & mut self ) {
753
+ for ( index, place) in self . checked_places . iter ( ) {
736
754
let local = place. local ;
737
755
if let & LocalInfo :: User ( BindingForm :: RefForGuard ( arm_local) ) =
738
- body. local_decls [ local] . local_info ( )
756
+ self . body . local_decls [ local] . local_info ( )
739
757
{
740
758
debug_assert ! ( place. projection. is_empty( ) ) ;
741
759
742
760
// Local to use in the arm.
743
- let Some ( ( arm_index, _proj) ) = checked_places. get ( arm_local. into ( ) ) else {
761
+ let Some ( ( arm_index, _proj) ) = self . checked_places . get ( arm_local. into ( ) ) else {
744
762
continue ;
745
763
} ;
746
764
debug_assert_ne ! ( index, arm_index) ;
@@ -775,14 +793,10 @@ impl AssignmentResult {
775
793
}
776
794
777
795
/// Compute captures that are fully dead.
778
- fn compute_dead_captures < ' tcx > (
779
- & self ,
780
- checked_places : & PlaceSet < ' tcx > ,
781
- num_captures : usize ,
782
- ) -> DenseBitSet < FieldIdx > {
796
+ fn compute_dead_captures ( & self , num_captures : usize ) -> DenseBitSet < FieldIdx > {
783
797
// Report to caller the set of dead captures.
784
798
let mut dead_captures = DenseBitSet :: new_empty ( num_captures) ;
785
- for ( index, place) in checked_places. iter ( ) {
799
+ for ( index, place) in self . checked_places . iter ( ) {
786
800
if self . ever_live . contains ( index) {
787
801
continue ;
788
802
}
@@ -803,16 +817,11 @@ impl AssignmentResult {
803
817
}
804
818
805
819
/// Report fully unused locals, and forget the corresponding assignments.
806
- fn report_fully_unused < ' tcx > (
807
- & mut self ,
808
- tcx : TyCtxt < ' tcx > ,
809
- checked_places : & PlaceSet < ' tcx > ,
810
- body : & Body < ' tcx > ,
811
- ) {
812
- let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
820
+ fn report_fully_unused ( & mut self ) {
821
+ let tcx = self . tcx ;
813
822
814
823
// First, report fully unused locals.
815
- for ( index, place) in checked_places. iter ( ) {
824
+ for ( index, place) in self . checked_places . iter ( ) {
816
825
if self . ever_live . contains ( index) {
817
826
continue ;
818
827
}
@@ -823,21 +832,21 @@ impl AssignmentResult {
823
832
}
824
833
825
834
let local = place. local ;
826
- let decl = & body. local_decls [ local] ;
835
+ let decl = & self . body . local_decls [ local] ;
827
836
828
837
if decl. from_compiler_desugaring ( ) {
829
838
continue ;
830
839
}
831
840
832
841
// Only report actual user-defined binding from now on.
833
842
let LocalInfo :: User ( BindingForm :: Var ( binding) ) = decl. local_info ( ) else { continue } ;
834
- let Some ( hir_id) = decl. source_info . scope . lint_root ( & body. source_scopes ) else {
843
+ let Some ( hir_id) = decl. source_info . scope . lint_root ( & self . body . source_scopes ) else {
835
844
continue ;
836
845
} ;
837
846
838
847
let introductions = & binding. introductions ;
839
848
840
- let Some ( ( name, def_span) ) = checked_places. names [ index] else { continue } ;
849
+ let Some ( ( name, def_span) ) = self . checked_places . names [ index] else { continue } ;
841
850
842
851
// #117284, when `ident_span` and `def_span` have different contexts
843
852
// we can't provide a good suggestion, instead we pointed out the spans from macro
@@ -857,7 +866,7 @@ impl AssignmentResult {
857
866
def_span,
858
867
errors:: UnusedVariable {
859
868
name,
860
- string_interp : maybe_suggest_literal_matching_name ( body, name) ,
869
+ string_interp : maybe_suggest_literal_matching_name ( self . body , name) ,
861
870
sugg,
862
871
} ,
863
872
) ;
@@ -888,11 +897,11 @@ impl AssignmentResult {
888
897
// This is probably a drop-guard, so we do not issue a warning there.
889
898
if maybe_drop_guard (
890
899
tcx,
891
- typing_env,
900
+ self . typing_env ,
892
901
index,
893
902
& self . ever_dropped ,
894
- checked_places,
895
- body,
903
+ self . checked_places ,
904
+ self . body ,
896
905
) {
897
906
statements. clear ( ) ;
898
907
continue ;
@@ -944,7 +953,7 @@ impl AssignmentResult {
944
953
spans,
945
954
errors:: UnusedVariable {
946
955
name,
947
- string_interp : maybe_suggest_literal_matching_name ( body, name) ,
956
+ string_interp : maybe_suggest_literal_matching_name ( self . body , name) ,
948
957
sugg,
949
958
} ,
950
959
) ;
@@ -953,25 +962,26 @@ impl AssignmentResult {
953
962
954
963
/// Second, report unused assignments that do not correspond to initialization.
955
964
/// Initializations have been removed in the previous loop reporting unused variables.
956
- fn report_unused_assignments < ' tcx > (
957
- self ,
958
- tcx : TyCtxt < ' tcx > ,
959
- body_def_id : LocalDefId ,
960
- checked_places : & PlaceSet < ' tcx > ,
961
- body : & Body < ' tcx > ,
962
- ) {
963
- let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
965
+ fn report_unused_assignments ( self ) {
966
+ let tcx = self . tcx ;
964
967
965
968
for ( index, statements) in self . assignments . into_iter_enumerated ( ) {
966
969
if statements. is_empty ( ) {
967
970
continue ;
968
971
}
969
972
970
- let Some ( ( name, decl_span) ) = checked_places. names [ index] else { continue } ;
973
+ let Some ( ( name, decl_span) ) = self . checked_places . names [ index] else { continue } ;
971
974
972
975
// We have outstanding assignments and with non-trivial drop.
973
976
// This is probably a drop-guard, so we do not issue a warning there.
974
- if maybe_drop_guard ( tcx, typing_env, index, & self . ever_dropped , checked_places, body) {
977
+ if maybe_drop_guard (
978
+ tcx,
979
+ self . typing_env ,
980
+ index,
981
+ & self . ever_dropped ,
982
+ self . checked_places ,
983
+ self . body ,
984
+ ) {
975
985
continue ;
976
986
}
977
987
@@ -983,18 +993,18 @@ impl AssignmentResult {
983
993
}
984
994
985
995
// Report the dead assignment.
986
- let Some ( hir_id) = source_info. scope . lint_root ( & body. source_scopes ) else {
996
+ let Some ( hir_id) = source_info. scope . lint_root ( & self . body . source_scopes ) else {
987
997
continue ;
988
998
} ;
989
999
990
1000
match kind {
991
1001
AccessKind :: Assign => {
992
1002
let suggestion = annotate_mut_binding_to_immutable_binding (
993
1003
tcx,
994
- checked_places. places [ index] ,
995
- body_def_id ,
1004
+ self . checked_places . places [ index] ,
1005
+ self . body . source . def_id ( ) . expect_local ( ) ,
996
1006
source_info. span ,
997
- body,
1007
+ self . body ,
998
1008
) ;
999
1009
tcx. emit_node_span_lint (
1000
1010
lint:: builtin:: UNUSED_ASSIGNMENTS ,
0 commit comments