Skip to content

Commit 172c05c

Browse files
committed
only visit reachable blocks, do not use a visitor
1 parent 5343550 commit 172c05c

File tree

1 file changed

+16
-28
lines changed
  • compiler/rustc_const_eval/src/check_consts

1 file changed

+16
-28
lines changed

compiler/rustc_const_eval/src/check_consts/check.rs

+16-28
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use rustc_middle::ty::adjustment::PointerCoercion;
1818
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
1919
use rustc_mir_dataflow::impls::MaybeStorageLive;
2020
use rustc_mir_dataflow::storage::always_storage_live_locals;
21-
use rustc_mir_dataflow::{Analysis, ResultsCursor};
21+
use rustc_mir_dataflow::Analysis;
2222
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
2323
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
2424
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
@@ -275,40 +275,28 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
275275
// A local is "transient" if it is guaranteed dead at all `Return`.
276276
// So first compute the say of "maybe live" locals at each program point.
277277
let always_live_locals = &always_storage_live_locals(&ccx.body);
278-
let maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
279-
.into_engine(ccx.tcx, &ccx.body)
280-
.iterate_to_fixpoint()
281-
.into_results_cursor(&ccx.body);
278+
let mut maybe_storage_live =
279+
MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
280+
.into_engine(ccx.tcx, &ccx.body)
281+
.iterate_to_fixpoint()
282+
.into_results_cursor(&ccx.body);
282283

283284
// And then check all `Return` in the MIR, and if a local is "maybe live" at a
284285
// `Return` then it is definitely not transient.
285-
struct TransientLocalVisitor<'a, 'tcx> {
286-
maybe_storage_live: ResultsCursor<'a, 'tcx, MaybeStorageLive<'a>>,
287-
transient: BitSet<Local>,
288-
}
289-
impl<'a, 'tcx> Visitor<'tcx> for TransientLocalVisitor<'a, 'tcx> {
290-
fn visit_terminator(
291-
&mut self,
292-
terminator: &Terminator<'tcx>,
293-
location: Location,
294-
) {
295-
if matches!(terminator.kind, TerminatorKind::Return) {
296-
self.maybe_storage_live.seek_after_primary_effect(location);
297-
for local in self.maybe_storage_live.get().iter() {
298-
// If a local may be live here, it is definitely not transient.
299-
self.transient.remove(local);
300-
}
286+
let mut transient = BitSet::new_filled(ccx.body.local_decls.len());
287+
// Make sure to only visit reachable blocks, the dataflow engine can ICE otherwise.
288+
for (bb, data) in traversal::reachable(&ccx.body) {
289+
if matches!(data.terminator().kind, TerminatorKind::Return) {
290+
let location = ccx.body.terminator_loc(bb);
291+
maybe_storage_live.seek_after_primary_effect(location);
292+
for local in maybe_storage_live.get().iter() {
293+
// If a local may be live here, it is definitely not transient.
294+
transient.remove(local);
301295
}
302296
}
303297
}
304298

305-
let mut v = TransientLocalVisitor {
306-
maybe_storage_live,
307-
transient: BitSet::new_filled(ccx.body.local_decls.len()),
308-
};
309-
v.visit_body(&ccx.body);
310-
311-
v.transient
299+
transient
312300
})
313301
.contains(local)
314302
}

0 commit comments

Comments
 (0)