Skip to content

Commit a23d826

Browse files
committed
Lazily check if types need dropping.
1 parent 65c7a78 commit a23d826

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
@@ -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

Comments
 (0)