]>
git.proxmox.com Git - rustc.git/blob - 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.
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.
11 //! This pass erases all early-bound regions from the types occurring in the MIR.
12 //! We want to do this once just before codegen, so codegen does not have to take
13 //! care erasing regions all over the place.
14 //! NOTE: We do NOT erase regions of statements that are relevant for
15 //! "types-as-contracts"-validation, namely, AcquireValid, ReleaseValid, and EndRegion.
17 use rustc
::ty
::subst
::Substs
;
18 use rustc
::ty
::{self, Ty, TyCtxt}
;
20 use rustc
::mir
::visit
::{MutVisitor, TyContext}
;
21 use transform
::{MirPass, MirSource}
;
23 struct EraseRegionsVisitor
<'a
, 'tcx
: 'a
> {
24 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
25 in_validation_statement
: bool
,
28 impl<'a
, 'tcx
> EraseRegionsVisitor
<'a
, 'tcx
> {
29 pub fn new(tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>) -> Self {
32 in_validation_statement
: false,
37 impl<'a
, 'tcx
> MutVisitor
<'tcx
> for EraseRegionsVisitor
<'a
, 'tcx
> {
38 fn visit_ty(&mut self, ty
: &mut Ty
<'tcx
>, _
: TyContext
) {
39 if !self.in_validation_statement
{
40 *ty
= self.tcx
.erase_regions(ty
);
45 fn visit_region(&mut self, region
: &mut ty
::Region
<'tcx
>, _
: Location
) {
46 *region
= self.tcx
.types
.re_erased
;
49 fn visit_const(&mut self, constant
: &mut &'tcx ty
::Const
<'tcx
>, _
: Location
) {
50 *constant
= self.tcx
.erase_regions(constant
);
53 fn visit_substs(&mut self, substs
: &mut &'tcx Substs
<'tcx
>, _
: Location
) {
54 *substs
= self.tcx
.erase_regions(substs
);
57 fn visit_statement(&mut self,
59 statement
: &mut Statement
<'tcx
>,
61 // Do NOT delete EndRegion if validation statements are emitted.
62 // Validation needs EndRegion.
63 if self.tcx
.sess
.opts
.debugging_opts
.mir_emit_validate
== 0 {
64 if let StatementKind
::EndRegion(_
) = statement
.kind
{
65 statement
.kind
= StatementKind
::Nop
;
69 self.in_validation_statement
= match statement
.kind
{
70 StatementKind
::Validate(..) => true,
73 self.super_statement(block
, statement
, location
);
74 self.in_validation_statement
= false;
78 pub struct EraseRegions
;
80 impl MirPass
for EraseRegions
{
81 fn run_pass
<'a
, 'tcx
>(&self,
82 tcx
: TyCtxt
<'a
, 'tcx
, 'tcx
>,
84 mir
: &mut Mir
<'tcx
>) {
85 EraseRegionsVisitor
::new(tcx
).visit_mir(mir
);