let mut passes = Passes::new();
passes.push_hook(mir::transform::dump_mir::DumpMir);
- // Insert AcquireValid and ReleaseValid calls. Conceptually, this
- // pass is actually part of MIR building.
- passes.push_pass(MIR_CONST, mir::transform::add_validation::AddValidation);
-
// Remove all `EndRegion` statements that are not involved in borrows.
passes.push_pass(MIR_CONST, mir::transform::clean_end_regions::CleanEndRegions);
passes.push_pass(MIR_CONST, mir::transform::type_check::TypeckMir);
passes.push_pass(MIR_CONST, mir::transform::rustc_peek::SanityCheck);
+ // We compute "constant qualifications" betwen MIR_CONST and MIR_VALIDATED.
+
// What we need to run borrowck etc.
passes.push_pass(MIR_VALIDATED, mir::transform::qualify_consts::QualifyAndPromoteConstants);
passes.push_pass(MIR_VALIDATED,
passes.push_pass(MIR_VALIDATED, mir::transform::simplify::SimplifyCfg::new("qualify-consts"));
passes.push_pass(MIR_VALIDATED, mir::transform::nll::NLL);
- // Optimizations begin.
- passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
- passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("no-landing-pads"));
+ // borrowck runs between MIR_VALIDATED and MIR_OPTIMIZED.
- // From here on out, regions are gone.
- passes.push_pass(MIR_OPTIMIZED, mir::transform::erase_regions::EraseRegions);
+ // These next passes must be executed together
+ passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
passes.push_pass(MIR_OPTIMIZED, mir::transform::elaborate_drops::ElaborateDrops);
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));
-
// No lifetime analysis based on borrowing can be done from here on out.
+
+ // AddValidation needs to run after ElaborateDrops and before EraseRegions.
+ passes.push_pass(MIR_OPTIMIZED, mir::transform::add_validation::AddValidation);
+
+ // From here on out, regions are gone.
+ passes.push_pass(MIR_OPTIMIZED, mir::transform::erase_regions::EraseRegions);
+
+ // Optimizations begin.
passes.push_pass(MIR_OPTIMIZED, mir::transform::inline::Inline);
passes.push_pass(MIR_OPTIMIZED, mir::transform::instcombine::InstCombine);
passes.push_pass(MIR_OPTIMIZED, mir::transform::deaggregator::Deaggregator);
struct GatherBorrowedRegions {
seen_regions: FxHashSet<CodeExtent>,
- in_validation_statement: bool,
}
struct DeleteTrivialEndRegions<'a> {
_source: MirSource,
mir: &mut Mir<'tcx>) {
let mut gather = GatherBorrowedRegions {
- seen_regions: FxHashSet(),
- in_validation_statement: false
+ seen_regions: FxHashSet()
};
gather.visit_mir(mir);
block: BasicBlock,
statement: &Statement<'tcx>,
location: Location) {
- self.in_validation_statement = match statement.kind {
- StatementKind::Validate(..) => true,
- _ => false,
- };
self.super_statement(block, statement, location);
- self.in_validation_statement = false;
}
fn visit_ty(&mut self, ty: &Ty<'tcx>, _: Lookup) {
- // Gather regions that occur in types inside AcquireValid/ReleaseValid statements
- if self.in_validation_statement {
- for re in ty.walk().flat_map(|t| t.regions()) {
- match *re {
- RegionKind::ReScope(ce) => { self.seen_regions.insert(ce); }
- _ => {},
- }
+ // Gather regions that occur in types
+ for re in ty.walk().flat_map(|t| t.regions()) {
+ match *re {
+ RegionKind::ReScope(ce) => { self.seen_regions.insert(ce); }
+ _ => {},
}
}
self.super_ty(ty);