@@ -135,8 +135,7 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den
135
135
. iterate_to_fixpoint ( tcx, body, None )
136
136
. into_results_cursor ( body) ;
137
137
138
- let mut assignments =
139
- AssignmentResult :: find_dead_assignments ( tcx, & checked_places, & mut live, body) ;
138
+ let mut assignments = AssignmentResult :: find_dead_assignments ( & checked_places, & mut live, body) ;
140
139
141
140
assignments. merge_guards ( & checked_places, body) ;
142
141
@@ -198,6 +197,33 @@ fn maybe_suggest_literal_matching_name(
198
197
finder. found
199
198
}
200
199
200
+ /// Return whether we should consider the current place as a drop guard and skip reporting.
201
+ fn maybe_drop_guard < ' tcx > (
202
+ tcx : TyCtxt < ' tcx > ,
203
+ typing_env : ty:: TypingEnv < ' tcx > ,
204
+ index : PlaceIndex ,
205
+ ever_dropped : & DenseBitSet < PlaceIndex > ,
206
+ checked_places : & PlaceSet < ' tcx > ,
207
+ body : & Body < ' tcx > ,
208
+ ) -> bool {
209
+ if ever_dropped. contains ( index) {
210
+ let ty = checked_places. places [ index] . ty ( & body. local_decls , tcx) . ty ;
211
+ matches ! (
212
+ ty. kind( ) ,
213
+ ty:: Closure ( ..)
214
+ | ty:: Coroutine ( ..)
215
+ | ty:: Tuple ( ..)
216
+ | ty:: Adt ( ..)
217
+ | ty:: Dynamic ( ..)
218
+ | ty:: Array ( ..)
219
+ | ty:: Slice ( ..)
220
+ | ty:: Alias ( ty:: Opaque , ..)
221
+ ) && ty. needs_drop ( tcx, typing_env)
222
+ } else {
223
+ false
224
+ }
225
+ }
226
+
201
227
/// Detect the following case
202
228
///
203
229
/// ```text
@@ -579,7 +605,6 @@ impl AssignmentResult {
579
605
/// Assignments are collected, even if they are live. Dead assignments are reported, and live
580
606
/// assignments are used to make diagnostics correct for match guards.
581
607
fn find_dead_assignments < ' tcx > (
582
- tcx : TyCtxt < ' tcx > ,
583
608
checked_places : & PlaceSet < ' tcx > ,
584
609
cursor : & mut ResultsCursor < ' _ , ' tcx , MaybeLivePlaces < ' _ , ' tcx > > ,
585
610
body : & Body < ' tcx > ,
@@ -610,24 +635,9 @@ impl AssignmentResult {
610
635
}
611
636
} ;
612
637
613
- let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
614
638
let mut record_drop = |place : Place < ' tcx > | {
615
639
if let Some ( ( index, & [ ] ) ) = checked_places. get ( place. as_ref ( ) ) {
616
- let ty = place. ty ( & body. local_decls , tcx) . ty ;
617
- let needs_drop = matches ! (
618
- ty. kind( ) ,
619
- ty:: Closure ( ..)
620
- | ty:: Coroutine ( ..)
621
- | ty:: Tuple ( ..)
622
- | ty:: Adt ( ..)
623
- | ty:: Dynamic ( ..)
624
- | ty:: Array ( ..)
625
- | ty:: Slice ( ..)
626
- | ty:: Alias ( ty:: Opaque , ..)
627
- ) && ty. needs_drop ( tcx, typing_env) ;
628
- if needs_drop {
629
- ever_dropped. insert ( index) ;
630
- }
640
+ ever_dropped. insert ( index) ;
631
641
}
632
642
} ;
633
643
@@ -800,6 +810,8 @@ impl AssignmentResult {
800
810
checked_places : & PlaceSet < ' tcx > ,
801
811
body : & Body < ' tcx > ,
802
812
) {
813
+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
814
+
803
815
// First, report fully unused locals.
804
816
for ( index, place) in checked_places. iter ( ) {
805
817
if self . ever_live . contains ( index) {
@@ -875,7 +887,15 @@ impl AssignmentResult {
875
887
if !statements. is_empty ( ) {
876
888
// We have a dead local with outstanding assignments and with non-trivial drop.
877
889
// This is probably a drop-guard, so we do not issue a warning there.
878
- if self . ever_dropped . contains ( index) {
890
+ if maybe_drop_guard (
891
+ tcx,
892
+ typing_env,
893
+ index,
894
+ & self . ever_dropped ,
895
+ checked_places,
896
+ body,
897
+ ) {
898
+ statements. clear ( ) ;
879
899
continue ;
880
900
}
881
901
@@ -941,6 +961,8 @@ impl AssignmentResult {
941
961
checked_places : & PlaceSet < ' tcx > ,
942
962
body : & Body < ' tcx > ,
943
963
) {
964
+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
965
+
944
966
for ( index, statements) in self . assignments . into_iter_enumerated ( ) {
945
967
if statements. is_empty ( ) {
946
968
continue ;
@@ -950,7 +972,7 @@ impl AssignmentResult {
950
972
951
973
// We have outstanding assignments and with non-trivial drop.
952
974
// This is probably a drop-guard, so we do not issue a warning there.
953
- if self . ever_dropped . contains ( index ) {
975
+ if maybe_drop_guard ( tcx , typing_env , index , & self . ever_dropped , checked_places , body ) {
954
976
continue ;
955
977
}
956
978
0 commit comments