Skip to content

Commit efdde24

Browse files
committed
Auto merge of #31324 - nagisa:mir-transforms, r=nikomatsakis
Having a `MirPass` provides literally no benefits over `MutVisitor`. Moreover using `MirPass` for `EraseRegions` basically makes the programmer to fix breakage from changing repr twice – in the visitor and eraseregions. Since `MutVisitor` implements all the “walking” inside the trait, that can be reused for `EraseRegions` too, basically resulting in less code duplication.
2 parents 26105b1 + 0b3ef97 commit efdde24

File tree

2 files changed

+68
-158
lines changed

2 files changed

+68
-158
lines changed

src/librustc_mir/mir_map.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ extern crate rustc_front;
2323
use build;
2424
use graphviz;
2525
use pretty;
26-
use transform::*;
26+
use transform::{simplify_cfg, MirPass};
2727
use rustc::dep_graph::DepNode;
2828
use rustc::mir::repr::Mir;
2929
use hair::cx::Cx;

src/librustc_mir/transform/erase_regions.rs

+67-157
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
1515
use rustc::middle::ty;
1616
use rustc::mir::repr::*;
17-
use transform::MirPass;
17+
use rustc::mir::visit::MutVisitor;
1818
use mir_map::MirMap;
19+
use transform::MirPass;
1920

2021
pub fn erase_regions<'tcx>(tcx: &ty::ctxt<'tcx>, mir_map: &mut MirMap<'tcx>) {
2122
let mut eraser = EraseRegions::new(tcx);
@@ -29,196 +30,105 @@ pub struct EraseRegions<'a, 'tcx: 'a> {
2930
tcx: &'a ty::ctxt<'tcx>,
3031
}
3132

32-
impl<'a, 'tcx> MirPass<'tcx> for EraseRegions<'a, 'tcx> {
33-
34-
fn run_on_mir(&mut self, mir: &mut Mir<'tcx>) {
35-
36-
for basic_block in &mut mir.basic_blocks {
37-
self.erase_regions_basic_block(basic_block);
38-
}
39-
40-
self.erase_regions_return_ty(&mut mir.return_ty);
41-
42-
self.erase_regions_tys(mir.var_decls.iter_mut().map(|d| &mut d.ty));
43-
self.erase_regions_tys(mir.arg_decls.iter_mut().map(|d| &mut d.ty));
44-
self.erase_regions_tys(mir.temp_decls.iter_mut().map(|d| &mut d.ty));
45-
}
46-
}
47-
4833
impl<'a, 'tcx> EraseRegions<'a, 'tcx> {
49-
5034
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> EraseRegions<'a, 'tcx> {
5135
EraseRegions {
5236
tcx: tcx
5337
}
5438
}
5539

56-
fn erase_regions_basic_block(&mut self,
57-
basic_block: &mut BasicBlockData<'tcx>) {
58-
for statement in &mut basic_block.statements {
59-
self.erase_regions_statement(statement);
40+
fn erase_regions_return_ty(&mut self, fn_output: &mut ty::FnOutput<'tcx>) {
41+
match *fn_output {
42+
ty::FnConverging(ref mut ty) => {
43+
*ty = self.tcx.erase_regions(ty);
44+
},
45+
ty::FnDiverging => {}
6046
}
61-
62-
self.erase_regions_terminator(basic_block.terminator_mut());
6347
}
6448

65-
fn erase_regions_statement(&mut self,
66-
statement: &mut Statement<'tcx>) {
67-
match statement.kind {
68-
StatementKind::Assign(ref mut lvalue, ref mut rvalue) => {
69-
self.erase_regions_lvalue(lvalue);
70-
self.erase_regions_rvalue(rvalue);
71-
}
49+
fn erase_regions_tys<'b, T>(&mut self, tys: T)
50+
where T: Iterator<Item = &'b mut ty::Ty<'tcx>>,
51+
'tcx: 'b
52+
{
53+
for ty in tys {
54+
*ty = self.tcx.erase_regions(ty);
7255
}
7356
}
57+
}
58+
59+
impl<'a, 'tcx> MirPass<'tcx> for EraseRegions<'a, 'tcx> {
60+
fn run_on_mir(&mut self, mir: &mut Mir<'tcx>) {
61+
self.visit_mir(mir);
62+
}
63+
}
7464

75-
fn erase_regions_terminator(&mut self,
76-
terminator: &mut Terminator<'tcx>) {
65+
impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegions<'a, 'tcx> {
66+
fn visit_mir(&mut self, mir: &mut Mir<'tcx>) {
67+
self.erase_regions_return_ty(&mut mir.return_ty);
68+
self.erase_regions_tys(mir.var_decls.iter_mut().map(|d| &mut d.ty));
69+
self.erase_regions_tys(mir.arg_decls.iter_mut().map(|d| &mut d.ty));
70+
self.erase_regions_tys(mir.temp_decls.iter_mut().map(|d| &mut d.ty));
71+
self.super_mir(mir);
72+
}
73+
74+
fn visit_terminator(&mut self, bb: BasicBlock, terminator: &mut Terminator<'tcx>) {
7775
match *terminator {
7876
Terminator::Goto { .. } |
7977
Terminator::Resume |
80-
Terminator::Return => {
78+
Terminator::Return |
79+
Terminator::If { .. } |
80+
Terminator::Switch { .. } |
81+
Terminator::Drop { .. } |
82+
Terminator::Call { .. } => {
8183
/* nothing to do */
82-
}
83-
Terminator::If { ref mut cond, .. } => {
84-
self.erase_regions_operand(cond);
85-
}
86-
Terminator::Switch { ref mut discr, .. } => {
87-
self.erase_regions_lvalue(discr);
88-
}
89-
Terminator::SwitchInt { ref mut discr, ref mut switch_ty, .. } => {
90-
self.erase_regions_lvalue(discr);
84+
},
85+
Terminator::SwitchInt { ref mut switch_ty, .. } => {
9186
*switch_ty = self.tcx.erase_regions(switch_ty);
9287
},
93-
Terminator::Drop { ref mut value, .. } => {
94-
self.erase_regions_lvalue(value);
95-
}
96-
Terminator::Call { ref mut func, ref mut args, ref mut destination, .. } => {
97-
if let Some((ref mut destination, _)) = *destination {
98-
self.erase_regions_lvalue(destination);
99-
}
100-
self.erase_regions_operand(func);
101-
for arg in &mut *args {
102-
self.erase_regions_operand(arg);
103-
}
104-
}
105-
}
106-
}
107-
108-
fn erase_regions_operand(&mut self, operand: &mut Operand<'tcx>) {
109-
match *operand {
110-
Operand::Consume(ref mut lvalue) => {
111-
self.erase_regions_lvalue(lvalue);
112-
}
113-
Operand::Constant(ref mut constant) => {
114-
self.erase_regions_constant(constant);
115-
}
116-
}
117-
}
118-
119-
fn erase_regions_lvalue(&mut self, lvalue: &mut Lvalue<'tcx>) {
120-
match *lvalue {
121-
Lvalue::Var(_) |
122-
Lvalue::Temp(_) |
123-
Lvalue::Arg(_) |
124-
Lvalue::Static(_) |
125-
Lvalue::ReturnPointer => {}
126-
Lvalue::Projection(ref mut lvalue_projection) => {
127-
self.erase_regions_lvalue(&mut lvalue_projection.base);
128-
match lvalue_projection.elem {
129-
ProjectionElem::Deref |
130-
ProjectionElem::Field(_) |
131-
ProjectionElem::Downcast(..) |
132-
ProjectionElem::ConstantIndex {..} => { /* nothing to do */ }
133-
ProjectionElem::Index(ref mut index) => {
134-
self.erase_regions_operand(index);
135-
}
136-
}
137-
}
13888
}
89+
self.super_terminator(bb, terminator);
13990
}
14091

141-
fn erase_regions_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>) {
92+
fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>) {
14293
match *rvalue {
143-
Rvalue::Use(ref mut operand) => {
144-
self.erase_regions_operand(operand)
145-
}
146-
Rvalue::Repeat(ref mut operand, ref mut value) => {
147-
self.erase_regions_operand(operand);
148-
value.ty = self.tcx.erase_regions(&value.ty);
149-
}
150-
Rvalue::Ref(ref mut region, _, ref mut lvalue) => {
151-
*region = ty::ReStatic;
152-
self.erase_regions_lvalue(lvalue);
153-
}
154-
Rvalue::Len(ref mut lvalue) => self.erase_regions_lvalue(lvalue),
155-
Rvalue::Cast(_, ref mut operand, ref mut ty) => {
156-
self.erase_regions_operand(operand);
157-
*ty = self.tcx.erase_regions(ty);
158-
}
159-
Rvalue::BinaryOp(_, ref mut operand1, ref mut operand2) => {
160-
self.erase_regions_operand(operand1);
161-
self.erase_regions_operand(operand2);
162-
}
163-
Rvalue::UnaryOp(_, ref mut operand) => {
164-
self.erase_regions_operand(operand);
165-
}
94+
Rvalue::Use(_) |
95+
Rvalue::Len(_) |
96+
Rvalue::BinaryOp(_, _, _) |
97+
Rvalue::UnaryOp(_, _) |
98+
Rvalue::Slice { input: _, from_start: _, from_end: _ } |
99+
Rvalue::InlineAsm(_) => {},
100+
101+
Rvalue::Repeat(_, ref mut value) => value.ty = self.tcx.erase_regions(&value.ty),
102+
Rvalue::Ref(ref mut region, _, _) => *region = ty::ReStatic,
103+
Rvalue::Cast(_, _, ref mut ty) => *ty = self.tcx.erase_regions(ty),
166104
Rvalue::Box(ref mut ty) => *ty = self.tcx.erase_regions(ty),
167-
Rvalue::Aggregate(ref mut aggregate_kind, ref mut operands) => {
168-
match *aggregate_kind {
169-
AggregateKind::Vec |
170-
AggregateKind::Tuple => {},
171-
AggregateKind::Adt(_, _, ref mut substs) => {
172-
let erased = self.tcx.erase_regions(*substs);
173-
*substs = self.tcx.mk_substs(erased);
174-
}
175-
AggregateKind::Closure(def_id, ref mut closure_substs) => {
176-
let cloned = Box::new(closure_substs.clone());
177-
let ty = self.tcx.mk_closure_from_closure_substs(def_id,
178-
cloned);
179-
let erased = self.tcx.erase_regions(&ty);
180-
*closure_substs = match erased.sty {
181-
ty::TyClosure(_, ref closure_substs) => &*closure_substs,
182-
_ => unreachable!()
183-
};
184-
}
185-
}
186-
for operand in &mut *operands {
187-
self.erase_regions_operand(operand);
188-
}
189-
}
190-
Rvalue::Slice { ref mut input, .. } => {
191-
self.erase_regions_lvalue(input);
105+
106+
107+
Rvalue::Aggregate(AggregateKind::Vec, _) |
108+
Rvalue::Aggregate(AggregateKind::Tuple, _) => {},
109+
Rvalue::Aggregate(AggregateKind::Adt(_, _, ref mut substs), _) =>
110+
*substs = self.tcx.mk_substs(self.tcx.erase_regions(*substs)),
111+
Rvalue::Aggregate(AggregateKind::Closure(def_id, ref mut closure_substs), _) => {
112+
let cloned = Box::new(closure_substs.clone());
113+
let ty = self.tcx.mk_closure_from_closure_substs(def_id, cloned);
114+
let erased = self.tcx.erase_regions(&ty);
115+
*closure_substs = match erased.sty {
116+
ty::TyClosure(_, ref closure_substs) => &*closure_substs,
117+
_ => unreachable!()
118+
};
192119
}
193-
Rvalue::InlineAsm(_) => {},
194120
}
121+
self.super_rvalue(rvalue);
195122
}
196123

197-
fn erase_regions_constant(&mut self, constant: &mut Constant<'tcx>) {
124+
fn visit_constant(&mut self, constant: &mut Constant<'tcx>) {
198125
constant.ty = self.tcx.erase_regions(&constant.ty);
199126
match constant.literal {
200127
Literal::Item { ref mut substs, .. } => {
201128
*substs = self.tcx.mk_substs(self.tcx.erase_regions(substs));
202129
}
203130
Literal::Value { .. } => { /* nothing to do */ }
204131
}
205-
}
206-
207-
fn erase_regions_return_ty(&mut self, fn_output: &mut ty::FnOutput<'tcx>) {
208-
match *fn_output {
209-
ty::FnConverging(ref mut ty) => {
210-
*ty = self.tcx.erase_regions(ty);
211-
},
212-
ty::FnDiverging => {}
213-
}
214-
}
215-
216-
fn erase_regions_tys<'b, T>(&mut self, tys: T)
217-
where T: Iterator<Item = &'b mut ty::Ty<'tcx>>,
218-
'tcx: 'b
219-
{
220-
for ty in tys {
221-
*ty = self.tcx.erase_regions(ty);
222-
}
132+
self.super_constant(constant);
223133
}
224134
}

0 commit comments

Comments
 (0)