@@ -134,8 +134,7 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den
134134 . iterate_to_fixpoint ( tcx, body, None )
135135 . into_results_cursor ( body) ;
136136
137- let mut assignments =
138- AssignmentResult :: find_dead_assignments ( tcx, & checked_places, & mut live, body) ;
137+ let mut assignments = AssignmentResult :: find_dead_assignments ( & checked_places, & mut live, body) ;
139138
140139 assignments. merge_guards ( & checked_places, body) ;
141140
@@ -197,6 +196,33 @@ fn maybe_suggest_literal_matching_name(
197196 finder. found
198197}
199198
199+ /// Return whether we should consider the current place as a drop guard and skip reporting.
200+ fn maybe_drop_guard < ' tcx > (
201+ tcx : TyCtxt < ' tcx > ,
202+ typing_env : ty:: TypingEnv < ' tcx > ,
203+ index : PlaceIndex ,
204+ ever_dropped : & DenseBitSet < PlaceIndex > ,
205+ checked_places : & PlaceSet < ' tcx > ,
206+ body : & Body < ' tcx > ,
207+ ) -> bool {
208+ if ever_dropped. contains ( index) {
209+ let ty = checked_places. places [ index] . ty ( & body. local_decls , tcx) . ty ;
210+ matches ! (
211+ ty. kind( ) ,
212+ ty:: Closure ( ..)
213+ | ty:: Coroutine ( ..)
214+ | ty:: Tuple ( ..)
215+ | ty:: Adt ( ..)
216+ | ty:: Dynamic ( ..)
217+ | ty:: Array ( ..)
218+ | ty:: Slice ( ..)
219+ | ty:: Alias ( ty:: Opaque , ..)
220+ ) && ty. needs_drop ( tcx, typing_env)
221+ } else {
222+ false
223+ }
224+ }
225+
200226/// Detect the following case
201227///
202228/// ```text
@@ -578,7 +604,6 @@ impl AssignmentResult {
578604 /// Assignments are collected, even if they are live. Dead assignments are reported, and live
579605 /// assignments are used to make diagnostics correct for match guards.
580606 fn find_dead_assignments < ' tcx > (
581- tcx : TyCtxt < ' tcx > ,
582607 checked_places : & PlaceSet < ' tcx > ,
583608 cursor : & mut ResultsCursor < ' _ , ' tcx , MaybeLivePlaces < ' _ , ' tcx > > ,
584609 body : & Body < ' tcx > ,
@@ -609,24 +634,9 @@ impl AssignmentResult {
609634 }
610635 } ;
611636
612- let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
613637 let mut record_drop = |place : Place < ' tcx > | {
614638 if let Some ( ( index, & [ ] ) ) = checked_places. get ( place. as_ref ( ) ) {
615- let ty = place. ty ( & body. local_decls , tcx) . ty ;
616- let needs_drop = matches ! (
617- ty. kind( ) ,
618- ty:: Closure ( ..)
619- | ty:: Coroutine ( ..)
620- | ty:: Tuple ( ..)
621- | ty:: Adt ( ..)
622- | ty:: Dynamic ( ..)
623- | ty:: Array ( ..)
624- | ty:: Slice ( ..)
625- | ty:: Alias ( ty:: Opaque , ..)
626- ) && ty. needs_drop ( tcx, typing_env) ;
627- if needs_drop {
628- ever_dropped. insert ( index) ;
629- }
639+ ever_dropped. insert ( index) ;
630640 }
631641 } ;
632642
@@ -799,6 +809,8 @@ impl AssignmentResult {
799809 checked_places : & PlaceSet < ' tcx > ,
800810 body : & Body < ' tcx > ,
801811 ) {
812+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
813+
802814 // First, report fully unused locals.
803815 for ( index, place) in checked_places. iter ( ) {
804816 if self . ever_live . contains ( index) {
@@ -874,7 +886,15 @@ impl AssignmentResult {
874886 if !statements. is_empty ( ) {
875887 // We have a dead local with outstanding assignments and with non-trivial drop.
876888 // This is probably a drop-guard, so we do not issue a warning there.
877- if self . ever_dropped . contains ( index) {
889+ if maybe_drop_guard (
890+ tcx,
891+ typing_env,
892+ index,
893+ & self . ever_dropped ,
894+ checked_places,
895+ body,
896+ ) {
897+ statements. clear ( ) ;
878898 continue ;
879899 }
880900
@@ -940,6 +960,8 @@ impl AssignmentResult {
940960 checked_places : & PlaceSet < ' tcx > ,
941961 body : & Body < ' tcx > ,
942962 ) {
963+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
964+
943965 for ( index, statements) in self . assignments . into_iter_enumerated ( ) {
944966 if statements. is_empty ( ) {
945967 continue ;
@@ -949,7 +971,7 @@ impl AssignmentResult {
949971
950972 // We have outstanding assignments and with non-trivial drop.
951973 // This is probably a drop-guard, so we do not issue a warning there.
952- if self . ever_dropped . contains ( index ) {
974+ if maybe_drop_guard ( tcx , typing_env , index , & self . ever_dropped , checked_places , body ) {
953975 continue ;
954976 }
955977
0 commit comments