Skip to content

Commit fb2c30b

Browse files
committed
Lazily check if types need dropping.
1 parent 38dcfc6 commit fb2c30b

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

Comments
 (0)