@@ -133,8 +133,7 @@ pub(crate) fn check_liveness<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Den
133133 . iterate_to_fixpoint ( tcx, body, None )
134134 . into_results_cursor ( body) ;
135135
136- let mut assignments =
137- AssignmentResult :: find_dead_assignments ( tcx, & checked_places, & mut live, body) ;
136+ let mut assignments = AssignmentResult :: find_dead_assignments ( & checked_places, & mut live, body) ;
138137
139138 assignments. merge_guards ( & checked_places, body) ;
140139
@@ -196,6 +195,33 @@ fn maybe_suggest_literal_matching_name(
196195 finder. found
197196}
198197
198+ /// Return whether we should consider the current place as a drop guard and skip reporting.
199+ fn maybe_drop_guard < ' tcx > (
200+ tcx : TyCtxt < ' tcx > ,
201+ typing_env : ty:: TypingEnv < ' tcx > ,
202+ index : PlaceIndex ,
203+ ever_dropped : & DenseBitSet < PlaceIndex > ,
204+ checked_places : & PlaceSet < ' tcx > ,
205+ body : & Body < ' tcx > ,
206+ ) -> bool {
207+ if ever_dropped. contains ( index) {
208+ let ty = checked_places. places [ index] . ty ( & body. local_decls , tcx) . ty ;
209+ matches ! (
210+ ty. kind( ) ,
211+ ty:: Closure ( ..)
212+ | ty:: Coroutine ( ..)
213+ | ty:: Tuple ( ..)
214+ | ty:: Adt ( ..)
215+ | ty:: Dynamic ( ..)
216+ | ty:: Array ( ..)
217+ | ty:: Slice ( ..)
218+ | ty:: Alias ( ty:: Opaque , ..)
219+ ) && ty. needs_drop ( tcx, typing_env)
220+ } else {
221+ false
222+ }
223+ }
224+
199225/// Detect the following case
200226///
201227/// ```text
@@ -577,7 +603,6 @@ impl AssignmentResult {
577603 /// Assignments are collected, even if they are live. Dead assignments are reported, and live
578604 /// assignments are used to make diagnostics correct for match guards.
579605 fn find_dead_assignments < ' tcx > (
580- tcx : TyCtxt < ' tcx > ,
581606 checked_places : & PlaceSet < ' tcx > ,
582607 cursor : & mut ResultsCursor < ' _ , ' tcx , MaybeLivePlaces < ' _ , ' tcx > > ,
583608 body : & Body < ' tcx > ,
@@ -608,24 +633,9 @@ impl AssignmentResult {
608633 }
609634 } ;
610635
611- let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
612636 let mut record_drop = |place : Place < ' tcx > | {
613637 if let Some ( ( index, & [ ] ) ) = checked_places. get ( place. as_ref ( ) ) {
614- let ty = place. ty ( & body. local_decls , tcx) . ty ;
615- let needs_drop = matches ! (
616- ty. kind( ) ,
617- ty:: Closure ( ..)
618- | ty:: Coroutine ( ..)
619- | ty:: Tuple ( ..)
620- | ty:: Adt ( ..)
621- | ty:: Dynamic ( ..)
622- | ty:: Array ( ..)
623- | ty:: Slice ( ..)
624- | ty:: Alias ( ty:: Opaque , ..)
625- ) && ty. needs_drop ( tcx, typing_env) ;
626- if needs_drop {
627- ever_dropped. insert ( index) ;
628- }
638+ ever_dropped. insert ( index) ;
629639 }
630640 } ;
631641
@@ -798,6 +808,8 @@ impl AssignmentResult {
798808 checked_places : & PlaceSet < ' tcx > ,
799809 body : & Body < ' tcx > ,
800810 ) {
811+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
812+
801813 // First, report fully unused locals.
802814 for ( index, place) in checked_places. iter ( ) {
803815 if self . ever_live . contains ( index) {
@@ -873,7 +885,15 @@ impl AssignmentResult {
873885 if !statements. is_empty ( ) {
874886 // We have a dead local with outstanding assignments and with non-trivial drop.
875887 // This is probably a drop-guard, so we do not issue a warning there.
876- if self . ever_dropped . contains ( index) {
888+ if maybe_drop_guard (
889+ tcx,
890+ typing_env,
891+ index,
892+ & self . ever_dropped ,
893+ checked_places,
894+ body,
895+ ) {
896+ statements. clear ( ) ;
877897 continue ;
878898 }
879899
@@ -939,6 +959,8 @@ impl AssignmentResult {
939959 checked_places : & PlaceSet < ' tcx > ,
940960 body : & Body < ' tcx > ,
941961 ) {
962+ let typing_env = ty:: TypingEnv :: post_analysis ( tcx, body. source . def_id ( ) ) ;
963+
942964 for ( index, statements) in self . assignments . into_iter_enumerated ( ) {
943965 if statements. is_empty ( ) {
944966 continue ;
@@ -948,7 +970,7 @@ impl AssignmentResult {
948970
949971 // We have outstanding assignments and with non-trivial drop.
950972 // This is probably a drop-guard, so we do not issue a warning there.
951- if self . ever_dropped . contains ( index ) {
973+ if maybe_drop_guard ( tcx , typing_env , index , & self . ever_dropped , checked_places , body ) {
952974 continue ;
953975 }
954976
0 commit comments