From 1331cd4a8c7655875de6b94119f80f26c631925d Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 23 Feb 2018 20:54:18 +0000 Subject: [PATCH] Killing UserAssertTy in CleanupPostBorrowck pass. --- ...nd_regions.rs => cleanup_post_borrowck.rs} | 56 ++++++++++++++----- src/librustc_mir/transform/mod.rs | 7 ++- 2 files changed, 46 insertions(+), 17 deletions(-) rename src/librustc_mir/transform/{clean_end_regions.rs => cleanup_post_borrowck.rs} (61%) diff --git a/src/librustc_mir/transform/clean_end_regions.rs b/src/librustc_mir/transform/cleanup_post_borrowck.rs similarity index 61% rename from src/librustc_mir/transform/clean_end_regions.rs rename to src/librustc_mir/transform/cleanup_post_borrowck.rs index 6e8985d99d28..5fdadc32a767 100644 --- a/src/librustc_mir/transform/clean_end_regions.rs +++ b/src/librustc_mir/transform/cleanup_post_borrowck.rs @@ -8,16 +8,27 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! This module provides one pass, `CleanEndRegions`, that reduces the -//! set of `EndRegion` statements in the MIR. +//! This module provides two passes: //! -//! The "pass" is actually implemented as two traversals (aka visits) -//! of the input MIR. The first traversal, `GatherBorrowedRegions`, -//! finds all of the regions in the MIR that are involved in a borrow. +//! - `CleanEndRegions`, that reduces the set of `EndRegion` statements +//! in the MIR. +//! - `CleanUserAssertTy`, that replaces all `UserAssertTy` statements +//! with `Nop`. +//! +//! The `CleanEndRegions` "pass" is actually implemented as two +//! traversals (aka visits) of the input MIR. The first traversal, +//! `GatherBorrowedRegions`, finds all of the regions in the MIR +//! that are involved in a borrow. //! //! The second traversal, `DeleteTrivialEndRegions`, walks over the //! MIR and removes any `EndRegion` that is applied to a region that //! was not seen in the previous pass. +//! +//! The `CleanUserAssertTy` pass runs at a distinct time from the +//! `CleanEndRegions` pass. It is important that the `CleanUserAssertTy` +//! pass runs after the MIR borrowck so that the NLL type checker can +//! perform the type assertion when it encounters the `UserAssertTy` +//! statements. use rustc_data_structures::fx::FxHashSet; @@ -27,7 +38,7 @@ use rustc::mir::visit::{MutVisitor, Visitor, TyContext}; use rustc::ty::{Ty, RegionKind, TyCtxt}; use transform::{MirPass, MirSource}; -pub struct CleanEndRegions; +pub struct CleanupPostBorrowck; struct GatherBorrowedRegions { seen_regions: FxHashSet, @@ -37,19 +48,24 @@ struct DeleteTrivialEndRegions<'a> { seen_regions: &'a FxHashSet, } -impl MirPass for CleanEndRegions { +pub struct DeleteUserAssertTy; + +impl MirPass for CleanupPostBorrowck { fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, _source: MirSource, mir: &mut Mir<'tcx>) { - if !tcx.emit_end_regions() { return; } + if tcx.emit_end_regions() { + let mut gather = GatherBorrowedRegions { + seen_regions: FxHashSet() + }; + gather.visit_mir(mir); - let mut gather = GatherBorrowedRegions { - seen_regions: FxHashSet() - }; - gather.visit_mir(mir); + let mut delete = DeleteTrivialEndRegions { seen_regions: &mut gather.seen_regions }; + delete.visit_mir(mir); + } - let mut delete = DeleteTrivialEndRegions { seen_regions: &mut gather.seen_regions }; + let mut delete = DeleteUserAssertTy; delete.visit_mir(mir); } } @@ -93,7 +109,19 @@ impl<'a, 'tcx> MutVisitor<'tcx> for DeleteTrivialEndRegions<'a> { } if delete_it { - statement.kind = StatementKind::Nop; + statement.make_nop(); + } + self.super_statement(block, statement, location); + } +} + +impl<'tcx> MutVisitor<'tcx> for DeleteUserAssertTy { + fn visit_statement(&mut self, + block: BasicBlock, + statement: &mut Statement<'tcx>, + location: Location) { + if let StatementKind::UserAssertTy(..) = statement.kind { + statement.make_nop(); } self.super_statement(block, statement, location); } diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index a06571d0abdd..427528c4f6d9 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -25,7 +25,7 @@ use syntax_pos::Span; pub mod add_validation; pub mod add_moves_for_packed_drops; -pub mod clean_end_regions; +pub mod cleanup_post_borrowck; pub mod check_unsafety; pub mod simplify_branches; pub mod simplify; @@ -192,8 +192,9 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea let mut mir = tcx.mir_built(def_id).steal(); run_passes![tcx, mir, def_id, 0; - // Remove all `EndRegion` statements that are not involved in borrows. - clean_end_regions::CleanEndRegions, + // Remove all `UserAssertTy` statements and all `EndRegion` statements that are not + // involved in borrows. + cleanup_post_borrowck::CleanupPostBorrowck, // What we need to do constant evaluation. simplify::SimplifyCfg::new("initial"),