diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index e512099b93b..e5a36259fa4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2193,7 +2193,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut back_edge_stack = Vec::new(); predecessor_locations(self.body, location).for_each(|predecessor| { - if location.dominates(predecessor, &self.dominators) { + if location.dominates(predecessor, self.dominators()) { back_edge_stack.push(predecessor) } else { stack.push(predecessor); @@ -2305,7 +2305,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut has_predecessor = false; predecessor_locations(self.body, location).for_each(|predecessor| { - if location.dominates(predecessor, &self.dominators) { + if location.dominates(predecessor, self.dominators()) { back_edge_stack.push(predecessor) } else { stack.push(predecessor); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 2384f851a66..73ea7314b75 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -5,6 +5,7 @@ #![feature(let_chains)] #![feature(min_specialization)] #![feature(never_type)] +#![feature(once_cell)] #![feature(rustc_attrs)] #![feature(stmt_expr_attributes)] #![feature(trusted_step)] @@ -39,6 +40,7 @@ use rustc_span::{Span, Symbol}; use either::Either; use smallvec::SmallVec; +use std::cell::OnceCell; use std::cell::RefCell; use std::collections::BTreeMap; use std::rc::Rc; @@ -333,7 +335,7 @@ fn do_mir_borrowck<'tcx>( used_mut: Default::default(), used_mut_upvars: SmallVec::new(), borrow_set: Rc::clone(&borrow_set), - dominators: Dominators::dummy(), // not used + dominators: Default::default(), upvars: Vec::new(), local_names: IndexVec::from_elem(None, &promoted_body.local_decls), region_names: RefCell::default(), @@ -346,8 +348,6 @@ fn do_mir_borrowck<'tcx>( }; } - let dominators = body.basic_blocks.dominators(); - let mut mbcx = MirBorrowckCtxt { infcx, param_env, @@ -364,7 +364,7 @@ fn do_mir_borrowck<'tcx>( used_mut: Default::default(), used_mut_upvars: SmallVec::new(), borrow_set: Rc::clone(&borrow_set), - dominators, + dominators: Default::default(), upvars, local_names, region_names: RefCell::default(), @@ -534,7 +534,7 @@ struct MirBorrowckCtxt<'cx, 'tcx> { borrow_set: Rc>, /// Dominators for MIR - dominators: Dominators, + dominators: OnceCell>, /// Information about upvars not necessarily preserved in types or MIR upvars: Vec>, @@ -1051,7 +1051,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { (Read(kind), BorrowKind::Unique | BorrowKind::Mut { .. }) => { // Reading from mere reservations of mutable-borrows is OK. - if !is_active(&this.dominators, borrow, location) { + if !is_active(this.dominators(), borrow, location) { assert!(allow_two_phase_borrow(borrow.kind)); return Control::Continue; } @@ -2219,6 +2219,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { fn is_upvar_field_projection(&self, place_ref: PlaceRef<'tcx>) -> Option { path_utils::is_upvar_field_projection(self.infcx.tcx, &self.upvars, place_ref, self.body()) } + + fn dominators(&self) -> &Dominators { + self.dominators.get_or_init(|| self.body.basic_blocks.dominators()) + } } mod error { diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs index fb2a22e94a5..471457f61b2 100644 --- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs +++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs @@ -271,10 +271,6 @@ pub struct Dominators { } impl Dominators { - pub fn dummy() -> Self { - Self { post_order_rank: IndexVec::new(), immediate_dominators: IndexVec::new() } - } - pub fn is_reachable(&self, node: Node) -> bool { self.immediate_dominators[node].is_some() }