@@ -135,8 +135,7 @@ 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 =
139- AssignmentResult :: find_dead_assignments ( tcx, & checked_places, & mut live, body) ;
138+ let mut assignments = AssignmentResult :: find_dead_assignments ( & checked_places, & mut live, body) ;
140139
141140 assignments. merge_guards ( & checked_places, body) ;
142141
@@ -198,6 +197,33 @@ fn maybe_suggest_literal_matching_name(
198197 finder. found
199198}
200199
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+
201227/// Detect the following case
202228///
203229/// ```text
@@ -579,7 +605,6 @@ impl AssignmentResult {
579605 /// Assignments are collected, even if they are live. Dead assignments are reported, and live
580606 /// assignments are used to make diagnostics correct for match guards.
581607 fn find_dead_assignments < ' tcx > (
582- tcx : TyCtxt < ' tcx > ,
583608 checked_places : & PlaceSet < ' tcx > ,
584609 cursor : & mut ResultsCursor < ' _ , ' tcx , MaybeLivePlaces < ' _ , ' tcx > > ,
585610 body : & Body < ' tcx > ,
@@ -610,24 +635,9 @@ impl AssignmentResult {
610635 }
611636 } ;
612637
613- let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
614638 let mut record_drop = |place : Place < ' tcx > | {
615639 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) ;
631641 }
632642 } ;
633643
@@ -800,6 +810,8 @@ impl AssignmentResult {
800810 checked_places : & PlaceSet < ' tcx > ,
801811 body : & Body < ' tcx > ,
802812 ) {
813+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
814+
803815 // First, report fully unused locals.
804816 for ( index, place) in checked_places. iter ( ) {
805817 if self . ever_live . contains ( index) {
@@ -875,7 +887,15 @@ impl AssignmentResult {
875887 if !statements. is_empty ( ) {
876888 // We have a dead local with outstanding assignments and with non-trivial drop.
877889 // 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 ( ) ;
879899 continue ;
880900 }
881901
@@ -941,6 +961,8 @@ impl AssignmentResult {
941961 checked_places : & PlaceSet < ' tcx > ,
942962 body : & Body < ' tcx > ,
943963 ) {
964+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
965+
944966 for ( index, statements) in self . assignments . into_iter_enumerated ( ) {
945967 if statements. is_empty ( ) {
946968 continue ;
@@ -950,7 +972,7 @@ impl AssignmentResult {
950972
951973 // We have outstanding assignments and with non-trivial drop.
952974 // 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 ) {
954976 continue ;
955977 }
956978
0 commit comments