]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/transform/erase_regions.rs
Rollup merge of #68424 - estebank:suggest-borrow-for-non-copy-vec, r=davidtwco
[rust.git] / src / librustc_mir / transform / erase_regions.rs
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`.
6
7 use crate::transform::{MirPass, MirSource};
8 use rustc::mir::visit::{MutVisitor, TyContext};
9 use rustc::mir::*;
10 use rustc::ty::subst::SubstsRef;
11 use rustc::ty::{self, Ty, TyCtxt};
12
13 struct EraseRegionsVisitor<'tcx> {
14     tcx: TyCtxt<'tcx>,
15 }
16
17 impl EraseRegionsVisitor<'tcx> {
18     pub fn new(tcx: TyCtxt<'tcx>) -> Self {
19         EraseRegionsVisitor { tcx }
20     }
21 }
22
23 impl MutVisitor<'tcx> for EraseRegionsVisitor<'tcx> {
24     fn tcx(&self) -> TyCtxt<'tcx> {
25         self.tcx
26     }
27
28     fn visit_ty(&mut self, ty: &mut Ty<'tcx>, _: TyContext) {
29         *ty = self.tcx.erase_regions(ty);
30     }
31
32     fn visit_region(&mut self, region: &mut ty::Region<'tcx>, _: Location) {
33         *region = self.tcx.lifetimes.re_erased;
34     }
35
36     fn visit_const(&mut self, constant: &mut &'tcx ty::Const<'tcx>, _: Location) {
37         *constant = self.tcx.erase_regions(constant);
38     }
39
40     fn visit_substs(&mut self, substs: &mut SubstsRef<'tcx>, _: Location) {
41         *substs = self.tcx.erase_regions(substs);
42     }
43
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);
47
48             if new_ty != *ty {
49                 return Some(PlaceElem::Field(*field, new_ty));
50             }
51         }
52
53         None
54     }
55 }
56
57 pub struct EraseRegions;
58
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);
62     }
63 }