]> git.proxmox.com Git - rustc.git/blob - src/librustc_mir/transform/erase_regions.rs
New upstream version 1.20.0+dfsg1
[rustc.git] / src / librustc_mir / transform / erase_regions.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! This pass erases all early-bound regions from the types occuring in the MIR.
12 //! We want to do this once just before trans, so trans does not have to take
13 //! care erasing regions all over the place.
14
15 use rustc::ty::subst::Substs;
16 use rustc::ty::{Ty, TyCtxt, ClosureSubsts};
17 use rustc::mir::*;
18 use rustc::mir::visit::MutVisitor;
19 use rustc::mir::transform::{MirPass, MirSource};
20
21 struct EraseRegionsVisitor<'a, 'tcx: 'a> {
22 tcx: TyCtxt<'a, 'tcx, 'tcx>,
23 }
24
25 impl<'a, 'tcx> EraseRegionsVisitor<'a, 'tcx> {
26 pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Self {
27 EraseRegionsVisitor {
28 tcx: tcx
29 }
30 }
31 }
32
33 impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
34 fn visit_ty(&mut self, ty: &mut Ty<'tcx>) {
35 let old_ty = *ty;
36 *ty = self.tcx.erase_regions(&old_ty);
37 }
38
39 fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>) {
40 *substs = self.tcx.erase_regions(&{*substs});
41 }
42
43 fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
44 match *rvalue {
45 Rvalue::Ref(ref mut r, _, _) => {
46 *r = self.tcx.types.re_erased;
47 }
48 Rvalue::Use(..) |
49 Rvalue::Repeat(..) |
50 Rvalue::Len(..) |
51 Rvalue::Cast(..) |
52 Rvalue::BinaryOp(..) |
53 Rvalue::CheckedBinaryOp(..) |
54 Rvalue::UnaryOp(..) |
55 Rvalue::Discriminant(..) |
56 Rvalue::NullaryOp(..) |
57 Rvalue::Aggregate(..) => {
58 // These variants don't contain regions.
59 }
60 }
61 self.super_rvalue(rvalue, location);
62 }
63
64 fn visit_closure_substs(&mut self,
65 substs: &mut ClosureSubsts<'tcx>) {
66 *substs = self.tcx.erase_regions(substs);
67 }
68
69 fn visit_statement(&mut self,
70 block: BasicBlock,
71 statement: &mut Statement<'tcx>,
72 location: Location) {
73 if let StatementKind::EndRegion(_) = statement.kind {
74 statement.kind = StatementKind::Nop;
75 }
76 self.super_statement(block, statement, location);
77 }
78 }
79
80 pub struct EraseRegions;
81
82 impl MirPass for EraseRegions {
83 fn run_pass<'a, 'tcx>(&self,
84 tcx: TyCtxt<'a, 'tcx, 'tcx>,
85 _: MirSource,
86 mir: &mut Mir<'tcx>) {
87 EraseRegionsVisitor::new(tcx).visit_mir(mir);
88 }
89 }