Skip to content

Commit d953583

Browse files
committed
Lazily check if types need dropping.
1 parent f1a0ac7 commit d953583

File tree

1 file changed

+43
-21
lines changed

1 file changed

+43
-21
lines changed

compiler/rustc_mir_transform/src/liveness.rs

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)