1 //! This pass erases all early-bound regions from the types occurring in the MIR.
2 //! We want to do this once just before codegen, so codegen does not have to take
3 //! care erasing regions all over the place.
4 //! N.B., we do _not_ erase regions of statements that are relevant for
5 //! "types-as-contracts"-validation, namely, `AcquireValid` and `ReleaseValid`.
7 use crate::transform::{MirPass, MirSource};
8 use rustc::mir::visit::{MutVisitor, TyContext};
10 use rustc::ty::subst::SubstsRef;
11 use rustc::ty::{self, Ty, TyCtxt};
13 struct EraseRegionsVisitor<'tcx> {
17 impl EraseRegionsVisitor<'tcx> {
18 pub fn new(tcx: TyCtxt<'tcx>) -> Self {
19 EraseRegionsVisitor { tcx }
23 impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
24 fn tcx(&self) -> TyCtxt<'tcx> {
28 fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
29 *ty = self.tcx.erase_regions(ty);
32 fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
33 *region = self.tcx.lifetimes.re_erased;
36 fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) {
37 *constant = self.tcx.erase_regions(constant);
40 fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
41 *substs = self.tcx.erase_regions(substs);
44 fn process_projection_elem(&mut self, elem: &PlaceElem<'tcx>) -> Option<PlaceElem<'tcx>> {
45 if let PlaceElem::Field(field, ty) = elem {
46 let new_ty = self.tcx.erase_regions(ty);
49 return Some(PlaceElem::Field(*field, new_ty));
57 pub struct EraseRegions;
59 impl<'tcx> MirPass<'tcx> for EraseRegions {
60 fn run_pass(&self, tcx: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut BodyAndCache<'tcx>) {
61 EraseRegionsVisitor::new(tcx).visit_body(body);