Partially format librustc_mir with rustfmt.

This commit contains some of the changes proposed by a rustfmt invocation,
chosen based on the fairly non-deterministic metric of how much I liked the
change. I expect we will run rustfmt on this crate again later, probably
accepting more of its changes. For now, this is already an improvement over
the status-quo.
This commit is contained in:
Ms2ger 2015-10-07 14:37:42 +02:00
parent 0ea1305fad
commit c73e78ce64
24 changed files with 650 additions and 528 deletions

View File

@ -29,7 +29,7 @@ impl<'tcx> CFG<'tcx> {
pub fn end_point(&self, block: BasicBlock) -> ExecutionPoint {
ExecutionPoint {
block: block,
statement: self.block_data(block).statements.len() as u32
statement: self.block_data(block).statements.len() as u32,
}
}

View File

@ -10,7 +10,7 @@
//! See docs in build/expr/mod.rs
use build::{Builder};
use build::Builder;
use hair::*;
use repr::*;

View File

@ -30,18 +30,14 @@ impl<'a,'tcx> Builder<'a,'tcx> {
fn expr_as_lvalue(&mut self,
mut block: BasicBlock,
expr: Expr<'tcx>)
-> BlockAnd<Lvalue<'tcx>>
{
debug!("expr_as_lvalue(block={:?}, expr={:?})",
block, expr);
-> BlockAnd<Lvalue<'tcx>> {
debug!("expr_as_lvalue(block={:?}, expr={:?})", block, expr);
let this = self;
let expr_span = expr.span;
match expr.kind {
ExprKind::Scope { extent, value } => {
this.in_scope(extent, block, |this| {
this.as_lvalue(block, value)
})
this.in_scope(extent, block, |this| this.as_lvalue(block, value))
}
ExprKind::Field { lhs, name } => {
let lvalue = unpack!(block = this.as_lvalue(block, lhs));
@ -69,12 +65,11 @@ impl<'a,'tcx> Builder<'a,'tcx> {
idx.clone(),
Operand::Consume(len)));
let (success, failure) = (this.cfg.start_new_block(),
this.cfg.start_new_block());
let (success, failure) = (this.cfg.start_new_block(), this.cfg.start_new_block());
this.cfg.terminate(block,
Terminator::If {
cond: Operand::Consume(lt),
targets: [success, failure]
targets: [success, failure],
});
this.panic(failure);
success.and(slice.index(idx))

View File

@ -20,11 +20,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
/// If `expr` is an lvalue like `x`, this will introduce a
/// temporary `tmp = x`, so that we capture the value of `x` at
/// this time.
pub fn as_operand<M>(&mut self,
block: BasicBlock,
expr: M)
-> BlockAnd<Operand<'tcx>>
where M: Mirror<'tcx, Output=Expr<'tcx>>
pub fn as_operand<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Operand<'tcx>>
where M: Mirror<'tcx, Output = Expr<'tcx>>
{
let expr = self.hir.mirror(expr);
self.expr_as_operand(block, expr)
@ -33,16 +30,12 @@ impl<'a,'tcx> Builder<'a,'tcx> {
fn expr_as_operand(&mut self,
mut block: BasicBlock,
expr: Expr<'tcx>)
-> BlockAnd<Operand<'tcx>>
{
debug!("expr_as_operand(block={:?}, expr={:?})",
block, expr);
-> BlockAnd<Operand<'tcx>> {
debug!("expr_as_operand(block={:?}, expr={:?})", block, expr);
let this = self;
if let ExprKind::Scope { extent, value } = expr.kind {
return this.in_scope(extent, block, |this| {
this.as_operand(block, value)
});
return this.in_scope(extent, block, |this| this.as_operand(block, value));
}
let category = Category::of(&expr.kind).unwrap();

View File

@ -19,11 +19,8 @@ use repr::*;
impl<'a,'tcx> Builder<'a,'tcx> {
/// Compile `expr`, yielding an rvalue.
pub fn as_rvalue<M>(&mut self,
block: BasicBlock,
expr: M)
-> BlockAnd<Rvalue<'tcx>>
where M: Mirror<'tcx, Output=Expr<'tcx>>
pub fn as_rvalue<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Rvalue<'tcx>>
where M: Mirror<'tcx, Output = Expr<'tcx>>
{
let expr = self.hir.mirror(expr);
self.expr_as_rvalue(block, expr)
@ -32,19 +29,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
fn expr_as_rvalue(&mut self,
mut block: BasicBlock,
expr: Expr<'tcx>)
-> BlockAnd<Rvalue<'tcx>>
{
debug!("expr_as_rvalue(block={:?}, expr={:?})",
block, expr);
-> BlockAnd<Rvalue<'tcx>> {
debug!("expr_as_rvalue(block={:?}, expr={:?})", block, expr);
let this = self;
let expr_span = expr.span;
match expr.kind {
ExprKind::Scope { extent, value } => {
this.in_scope(extent, block, |this| {
this.as_rvalue(block, value)
})
this.in_scope(extent, block, |this| this.as_rvalue(block, value))
}
ExprKind::InlineAsm { asm } => {
block.and(Rvalue::InlineAsm(asm))
@ -162,11 +155,9 @@ impl<'a,'tcx> Builder<'a,'tcx> {
.map(|f| (f.name, unpack!(block = this.as_operand(block, f.expr))))
.collect();
let field_names =
this.hir.fields(adt_def, variant_index);
let field_names = this.hir.fields(adt_def, variant_index);
let base =
base.map(|base| unpack!(block = this.as_lvalue(block, base)));
let base = base.map(|base| unpack!(block = this.as_lvalue(block, base)));
// for the actual values we use, take either the
// expr the user specified or, if they didn't

View File

@ -18,29 +18,19 @@ use repr::*;
impl<'a,'tcx> Builder<'a,'tcx> {
/// Compile `expr` into a fresh temporary. This is used when building
/// up rvalues so as to freeze the value that will be consumed.
pub fn as_temp<M>(&mut self,
block: BasicBlock,
expr: M)
-> BlockAnd<Lvalue<'tcx>>
where M: Mirror<'tcx, Output=Expr<'tcx>>
pub fn as_temp<M>(&mut self, block: BasicBlock, expr: M) -> BlockAnd<Lvalue<'tcx>>
where M: Mirror<'tcx, Output = Expr<'tcx>>
{
let expr = self.hir.mirror(expr);
self.expr_as_temp(block, expr)
}
fn expr_as_temp(&mut self,
mut block: BasicBlock,
expr: Expr<'tcx>)
-> BlockAnd<Lvalue<'tcx>>
{
debug!("expr_as_temp(block={:?}, expr={:?})",
block, expr);
fn expr_as_temp(&mut self, mut block: BasicBlock, expr: Expr<'tcx>) -> BlockAnd<Lvalue<'tcx>> {
debug!("expr_as_temp(block={:?}, expr={:?})", block, expr);
let this = self;
if let ExprKind::Scope { extent, value } = expr.kind {
return this.in_scope(extent, block, |this| {
this.as_temp(block, value)
});
return this.in_scope(extent, block, |this| this.as_temp(block, value));
}
let expr_ty = expr.ty.clone();
@ -48,9 +38,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
let temp_lifetime = match expr.temp_lifetime {
Some(t) => t,
None => {
this.hir.span_bug(
expr.span,
&format!("no temp_lifetime for expr"));
this.hir.span_bug(expr.span, &format!("no temp_lifetime for expr"));
}
};
this.schedule_drop(expr.span, temp_lifetime, DropKind::Deep, &temp, expr_ty);

View File

@ -38,9 +38,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
match expr.kind {
ExprKind::Scope { extent, value } => {
this.in_scope(extent, block, |this| {
this.into(destination, block, value)
})
this.in_scope(extent, block, |this| this.into(destination, block, value))
}
ExprKind::Block { body: ast_block } => {
this.ast_block(destination, block, ast_block)
@ -204,8 +202,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
|loop_scope| loop_scope.continue_block)
}
ExprKind::Break { label } => {
this.break_or_continue(expr_span, label, block,
|loop_scope| loop_scope.break_block)
this.break_or_continue(expr_span, label, block, |loop_scope| loop_scope.break_block)
}
ExprKind::Return { value } => {
unpack!(block = this.into(&Lvalue::ReturnPointer, block, value));
@ -226,9 +223,9 @@ impl<'a,'tcx> Builder<'a,'tcx> {
data: CallData {
destination: destination.clone(),
func: fun,
args: args
args: args,
},
targets: [success, panic]
targets: [success, panic],
});
success.unit()
}

View File

@ -19,8 +19,11 @@ use hair::*;
use repr::*;
pub trait EvalInto<'tcx> {
fn eval_into<'a>(self, builder: &mut Builder<'a,'tcx>, destination: &Lvalue<'tcx>,
block: BasicBlock) -> BlockAnd<()>;
fn eval_into<'a>(self,
builder: &mut Builder<'a, 'tcx>,
destination: &Lvalue<'tcx>,
block: BasicBlock)
-> BlockAnd<()>;
}
impl<'a,'tcx> Builder<'a,'tcx> {
@ -37,7 +40,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
fn eval_into<'a>(self,
builder: &mut Builder<'a,'tcx>,
builder: &mut Builder<'a, 'tcx>,
destination: &Lvalue<'tcx>,
block: BasicBlock)
-> BlockAnd<()> {
@ -48,7 +51,7 @@ impl<'tcx> EvalInto<'tcx> for ExprRef<'tcx> {
impl<'tcx> EvalInto<'tcx> for Expr<'tcx> {
fn eval_into<'a>(self,
builder: &mut Builder<'a,'tcx>,
builder: &mut Builder<'a, 'tcx>,
destination: &Lvalue<'tcx>,
block: BasicBlock)
-> BlockAnd<()> {
@ -58,13 +61,13 @@ impl<'tcx> EvalInto<'tcx> for Expr<'tcx> {
impl<'tcx> EvalInto<'tcx> for Option<ExprRef<'tcx>> {
fn eval_into<'a>(self,
builder: &mut Builder<'a,'tcx>,
builder: &mut Builder<'a, 'tcx>,
destination: &Lvalue<'tcx>,
block: BasicBlock)
-> BlockAnd<()> {
match self {
Some(expr) => builder.into(destination, block, expr),
None => block.unit()
None => block.unit(),
}
}
}

View File

@ -33,10 +33,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
mut block: BasicBlock,
discriminant: ExprRef<'tcx>,
arms: Vec<Arm<'tcx>>)
-> BlockAnd<()>
{
let discriminant_lvalue =
unpack!(block = self.as_lvalue(block, discriminant));
-> BlockAnd<()> {
let discriminant_lvalue = unpack!(block = self.as_lvalue(block, discriminant));
// Before we do anything, create uninitialized variables with
// suitable extent for all of the bindings in this match. It's
@ -101,11 +99,10 @@ impl<'a,'tcx> Builder<'a,'tcx> {
pub fn expr_into_pattern(&mut self,
mut block: BasicBlock,
var_extent: CodeExtent, // lifetime of vars
var_extent: CodeExtent, // lifetime of vars
irrefutable_pat: PatternRef<'tcx>,
initializer: ExprRef<'tcx>)
-> BlockAnd<()>
{
-> BlockAnd<()> {
// optimize the case of `let x = ...`
let irrefutable_pat = self.hir.mirror(irrefutable_pat);
match irrefutable_pat.kind {
@ -115,16 +112,22 @@ impl<'a,'tcx> Builder<'a,'tcx> {
var,
ty,
subpattern: None } => {
let index = self.declare_binding(var_extent, mutability, name,
var, ty, irrefutable_pat.span);
let index = self.declare_binding(var_extent,
mutability,
name,
var,
ty,
irrefutable_pat.span);
let lvalue = Lvalue::Var(index);
return self.into(&lvalue, block, initializer);
}
_ => { }
_ => {}
}
let lvalue = unpack!(block = self.as_lvalue(block, initializer));
self.lvalue_into_pattern(block, var_extent,
PatternRef::Mirror(Box::new(irrefutable_pat)), &lvalue)
self.lvalue_into_pattern(block,
var_extent,
PatternRef::Mirror(Box::new(irrefutable_pat)),
&lvalue)
}
pub fn lvalue_into_pattern(&mut self,
@ -132,8 +135,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
var_extent: CodeExtent,
irrefutable_pat: PatternRef<'tcx>,
initializer: &Lvalue<'tcx>)
-> BlockAnd<()>
{
-> BlockAnd<()> {
// first, creating the bindings
self.declare_bindings(var_extent, irrefutable_pat.clone());
@ -150,10 +152,10 @@ impl<'a,'tcx> Builder<'a,'tcx> {
unpack!(block = self.simplify_candidate(block, &mut candidate));
if !candidate.match_pairs.is_empty() {
self.hir.span_bug(
candidate.match_pairs[0].pattern.span,
&format!("match pairs {:?} remaining after simplifying irrefutable pattern",
candidate.match_pairs));
self.hir.span_bug(candidate.match_pairs[0].pattern.span,
&format!("match pairs {:?} remaining after simplifying \
irrefutable pattern",
candidate.match_pairs));
}
// now apply the bindings, which will also declare the variables
@ -162,10 +164,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
block.unit()
}
pub fn declare_bindings(&mut self,
var_extent: CodeExtent,
pattern: PatternRef<'tcx>)
{
pub fn declare_bindings(&mut self, var_extent: CodeExtent, pattern: PatternRef<'tcx>) {
let pattern = self.hir.mirror(pattern);
match pattern.kind {
PatternKind::Binding { mutability, name, mode: _, var, ty, subpattern } => {
@ -180,8 +179,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
self.declare_bindings(var_extent, subpattern);
}
}
PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => {
}
PatternKind::Constant { .. } | PatternKind::Range { .. } | PatternKind::Wild => {}
PatternKind::Deref { subpattern } => {
self.declare_bindings(var_extent, subpattern);
}
@ -239,16 +237,28 @@ struct MatchPair<'tcx> {
#[derive(Clone, Debug, PartialEq)]
enum TestKind<'tcx> {
// test the branches of enum
Switch { adt_def: AdtDef<'tcx> },
Switch {
adt_def: AdtDef<'tcx>,
},
// test for equality
Eq { value: Literal<'tcx>, ty: Ty<'tcx> },
Eq {
value: Literal<'tcx>,
ty: Ty<'tcx>,
},
// test whether the value falls within an inclusive range
Range { lo: Literal<'tcx>, hi: Literal<'tcx>, ty: Ty<'tcx> },
Range {
lo: Literal<'tcx>,
hi: Literal<'tcx>,
ty: Ty<'tcx>,
},
// test length of the slice is equal to len
Len { len: usize, op: BinOp },
Len {
len: usize,
op: BinOp,
},
}
#[derive(Debug)]
@ -416,4 +426,3 @@ impl<'a,'tcx> Builder<'a,'tcx> {
index
}
}

View File

@ -33,15 +33,16 @@ impl<'a,'tcx> Builder<'a,'tcx> {
pub fn simplify_candidate(&mut self,
mut block: BasicBlock,
candidate: &mut Candidate<'tcx>)
-> BlockAnd<()>
{
-> BlockAnd<()> {
// repeatedly simplify match pairs until fixed point is reached
loop {
let match_pairs = mem::replace(&mut candidate.match_pairs, vec![]);
let mut progress = match_pairs.len(); // count how many were simplified
for match_pair in match_pairs {
match self.simplify_match_pair(block, match_pair, candidate) {
Ok(b) => { block = b; }
Ok(b) => {
block = b;
}
Err(match_pair) => {
candidate.match_pairs.push(match_pair);
progress -= 1; // this one was not simplified
@ -63,8 +64,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
mut block: BasicBlock,
match_pair: MatchPair<'tcx>,
candidate: &mut Candidate<'tcx>)
-> Result<BasicBlock, MatchPair<'tcx>>
{
-> Result<BasicBlock, MatchPair<'tcx>> {
match match_pair.pattern.kind {
PatternKind::Wild(..) => {
// nothing left to do
@ -115,8 +115,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
PatternKind::Leaf { subpatterns } => {
// tuple struct, match subpats (if any)
candidate.match_pairs.extend(
self.field_match_pairs(match_pair.lvalue, subpatterns));
candidate.match_pairs
.extend(self.field_match_pairs(match_pair.lvalue, subpatterns));
Ok(block)
}
@ -129,4 +129,3 @@ impl<'a,'tcx> Builder<'a,'tcx> {
}
}
}

View File

@ -37,23 +37,31 @@ impl<'a,'tcx> Builder<'a,'tcx> {
PatternKind::Constant { ref value } => {
Test {
span: match_pair.pattern.span,
kind: TestKind::Eq { value: value.clone(),
ty: match_pair.pattern.ty.clone() },
kind: TestKind::Eq {
value: value.clone(),
ty: match_pair.pattern.ty.clone(),
},
}
}
PatternKind::Range { ref lo, ref hi } => {
Test {
span: match_pair.pattern.span,
kind: TestKind::Range { lo: lo.clone(),
hi: hi.clone(),
ty: match_pair.pattern.ty.clone() },
kind: TestKind::Range {
lo: lo.clone(),
hi: hi.clone(),
ty: match_pair.pattern.ty.clone(),
},
}
}
PatternKind::Slice { ref prefix, ref slice, ref suffix } => {
let len = prefix.len() + suffix.len();
let op = if slice.is_some() {BinOp::Ge} else {BinOp::Eq};
let op = if slice.is_some() {
BinOp::Ge
} else {
BinOp::Eq
};
Test {
span: match_pair.pattern.span,
kind: TestKind::Len { len: len, op: op },
@ -102,11 +110,17 @@ impl<'a,'tcx> Builder<'a,'tcx> {
let hi = self.push_literal(block, test.span, ty.clone(), hi);
let item_ref = self.hir.partial_le(ty);
let lo_blocks =
self.call_comparison_fn(block, test.span, item_ref.clone(), lo, lvalue.clone());
let lo_blocks = self.call_comparison_fn(block,
test.span,
item_ref.clone(),
lo,
lvalue.clone());
let hi_blocks =
self.call_comparison_fn(lo_blocks[0], test.span, item_ref, lvalue.clone(), hi);
let hi_blocks = self.call_comparison_fn(lo_blocks[0],
test.span,
item_ref,
lvalue.clone(),
hi);
let failure = self.cfg.start_new_block();
self.cfg.terminate(lo_blocks[1], Terminator::Goto { target: failure });
@ -120,20 +134,18 @@ impl<'a,'tcx> Builder<'a,'tcx> {
let (actual, result) = (self.temp(usize_ty), self.temp(bool_ty));
// actual = len(lvalue)
self.cfg.push_assign(
block, test.span,
&actual, Rvalue::Len(lvalue.clone()));
self.cfg.push_assign(block, test.span, &actual, Rvalue::Len(lvalue.clone()));
// expected = <N>
let expected =
self.push_usize(block, test.span, len);
let expected = self.push_usize(block, test.span, len);
// result = actual == expected OR result = actual < expected
self.cfg.push_assign(
block, test.span,
&result, Rvalue::BinaryOp(op,
Operand::Consume(actual),
Operand::Consume(expected)));
self.cfg.push_assign(block,
test.span,
&result,
Rvalue::BinaryOp(op,
Operand::Consume(actual),
Operand::Consume(expected)));
// branch based on result
let target_blocks: Vec<_> = vec![self.cfg.start_new_block(),
@ -155,8 +167,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
lvalue1: Lvalue<'tcx>,
lvalue2: Lvalue<'tcx>)
-> Vec<BasicBlock> {
let target_blocks = vec![self.cfg.start_new_block(),
self.cfg.start_new_block()];
let target_blocks = vec![self.cfg.start_new_block(), self.cfg.start_new_block()];
let bool_ty = self.hir.bool_ty();
let eq_result = self.temp(bool_ty);
@ -176,7 +187,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
self.cfg.terminate(call_blocks[0],
Terminator::If {
cond: Operand::Consume(eq_result),
targets: [target_blocks[0], target_blocks[1]]
targets: [target_blocks[0], target_blocks[1]],
});
target_blocks
@ -209,7 +220,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
match_pairs));
block.and(match result {
Some(match_pairs) => Some(Candidate { match_pairs: match_pairs, ..candidate }),
None => None
None => None,
})
}
@ -341,8 +352,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
}
fn error_simplifyable(&mut self, match_pair: &MatchPair<'tcx>) -> ! {
self.hir.span_bug(
match_pair.pattern.span,
&format!("simplifyable pattern found: {:?}", match_pair.pattern))
self.hir.span_bug(match_pair.pattern.span,
&format!("simplifyable pattern found: {:?}", match_pair.pattern))
}
}

View File

@ -27,7 +27,9 @@ impl<'a,'tcx> Builder<'a,'tcx> {
.collect()
}
pub fn match_pair(&mut self, lvalue: Lvalue<'tcx>, pattern: PatternRef<'tcx>)
pub fn match_pair(&mut self,
lvalue: Lvalue<'tcx>,
pattern: PatternRef<'tcx>)
-> MatchPair<'tcx> {
let pattern = self.hir.mirror(pattern);
MatchPair::new(lvalue, pattern)
@ -54,17 +56,18 @@ impl<'a,'tcx> Builder<'a,'tcx> {
prefix: Vec<PatternRef<'tcx>>,
opt_slice: Option<PatternRef<'tcx>>,
suffix: Vec<PatternRef<'tcx>>)
-> BlockAnd<()>
{
-> BlockAnd<()> {
// If there is a `..P` pattern, create a temporary `t0` for
// the slice and then a match pair `t0 @ P`:
if let Some(slice) = opt_slice {
let slice = self.hir.mirror(slice);
let prefix_len = prefix.len();
let suffix_len = suffix.len();
let rvalue = Rvalue::Slice { input: lvalue.clone(),
from_start: prefix_len,
from_end: suffix_len };
let rvalue = Rvalue::Slice {
input: lvalue.clone(),
from_start: prefix_len,
from_end: suffix_len,
};
let temp = self.temp(slice.ty.clone()); // no need to schedule drop, temp is always copy
self.cfg.push_assign(block, slice.span, &temp, rvalue);
match_pairs.push(MatchPair::new(temp, slice));
@ -80,8 +83,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
match_pairs: &mut Vec<MatchPair<'tcx>>,
lvalue: Lvalue<'tcx>,
prefix: Vec<PatternRef<'tcx>>,
suffix: Vec<PatternRef<'tcx>>)
{
suffix: Vec<PatternRef<'tcx>>) {
let min_length = prefix.len() + suffix.len();
assert!(min_length < u32::MAX as usize);
let min_length = min_length as u32;
@ -121,6 +123,9 @@ impl<'a,'tcx> Builder<'a,'tcx> {
impl<'tcx> MatchPair<'tcx> {
pub fn new(lvalue: Lvalue<'tcx>, pattern: Pattern<'tcx>) -> MatchPair<'tcx> {
MatchPair { lvalue: lvalue, pattern: pattern }
MatchPair {
lvalue: lvalue,
pattern: pattern,
}
}
}

View File

@ -41,16 +41,16 @@ impl<'a,'tcx> Builder<'a,'tcx> {
literal: Literal<'tcx>)
-> Lvalue<'tcx> {
let temp = self.temp(ty.clone());
let constant = Constant { span: span, ty: ty, literal: literal };
let constant = Constant {
span: span,
ty: ty,
literal: literal,
};
self.cfg.push_assign_constant(block, span, &temp, constant);
temp
}
pub fn push_usize(&mut self,
block: BasicBlock,
span: Span,
value: usize)
-> Lvalue<'tcx> {
pub fn push_usize(&mut self, block: BasicBlock, span: Span, value: usize) -> Lvalue<'tcx> {
let usize_ty = self.hir.usize_ty();
let temp = self.temp(usize_ty);
self.cfg.push_assign_constant(
@ -68,7 +68,10 @@ impl<'a,'tcx> Builder<'a,'tcx> {
span: Span,
item_ref: ItemRef<'tcx>)
-> Lvalue<'tcx> {
let literal = Literal::Item { def_id: item_ref.def_id, substs: item_ref.substs };
let literal = Literal::Item {
def_id: item_ref.def_id,
substs: item_ref.substs,
};
self.push_literal(block, span, item_ref.ty, literal)
}
}

View File

@ -18,7 +18,7 @@ use syntax::ast;
use syntax::codemap::Span;
use tcx::{Cx, PatNode};
struct Builder<'a,'tcx:'a> {
struct Builder<'a, 'tcx: 'a> {
hir: Cx<'a, 'tcx>,
extents: FnvHashMap<CodeExtent, Vec<GraphExtent>>,
cfg: CFG<'tcx>,
@ -31,7 +31,7 @@ struct Builder<'a,'tcx:'a> {
}
struct CFG<'tcx> {
basic_blocks: Vec<BasicBlockData<'tcx>>
basic_blocks: Vec<BasicBlockData<'tcx>>,
}
///////////////////////////////////////////////////////////////////////////
@ -75,13 +75,13 @@ macro_rules! unpack {
///////////////////////////////////////////////////////////////////////////
// construct() -- the main entry point for building MIR for a function
pub fn construct<'a,'tcx>(mut hir: Cx<'a,'tcx>,
_span: Span,
implicit_arguments: Vec<Ty<'tcx>>,
explicit_arguments: Vec<(Ty<'tcx>, PatNode<'tcx>)>,
argument_extent: CodeExtent,
ast_block: &'tcx hir::Block)
-> Mir<'tcx> {
pub fn construct<'a, 'tcx>(mut hir: Cx<'a, 'tcx>,
_span: Span,
implicit_arguments: Vec<Ty<'tcx>>,
explicit_arguments: Vec<(Ty<'tcx>, PatNode<'tcx>)>,
argument_extent: CodeExtent,
ast_block: &'tcx hir::Block)
-> Mir<'tcx> {
let cfg = CFG { basic_blocks: vec![] };
// it's handy to have a temporary of type `()` sometimes, so make
@ -115,7 +115,7 @@ pub fn construct<'a,'tcx>(mut hir: Cx<'a,'tcx>,
builder.cfg.terminate(block, Terminator::Goto { target: END_BLOCK });
builder.cfg.terminate(END_BLOCK, Terminator::Return);
Mir {
Mir {
basic_blocks: builder.cfg.basic_blocks,
extents: builder.extents,
var_decls: builder.var_decls,
@ -177,4 +177,3 @@ mod matches;
mod misc;
mod scope;
mod stmt;

View File

@ -101,25 +101,27 @@ pub struct Scope<'tcx> {
#[derive(Clone, Debug)]
pub struct LoopScope {
pub extent: CodeExtent, // extent of the loop
pub extent: CodeExtent, // extent of the loop
pub continue_block: BasicBlock, // where to go on a `loop`
pub break_block: BasicBlock, // where to go on a `break
pub break_block: BasicBlock, // where to go on a `break
}
impl<'a,'tcx> Builder<'a,'tcx> {
/// Start a loop scope, which tracks where `continue` and `break`
/// should branch to. See module comment for more details.
pub fn in_loop_scope<F,R>(&mut self,
loop_block: BasicBlock,
break_block: BasicBlock,
f: F)
-> BlockAnd<R>
where F: FnOnce(&mut Builder<'a,'tcx>) -> BlockAnd<R>
pub fn in_loop_scope<F, R>(&mut self,
loop_block: BasicBlock,
break_block: BasicBlock,
f: F)
-> BlockAnd<R>
where F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd<R>
{
let extent = self.extent_of_innermost_scope().unwrap();
let loop_scope = LoopScope { extent: extent.clone(),
continue_block: loop_block,
break_block: break_block };
let loop_scope = LoopScope {
extent: extent.clone(),
continue_block: loop_block,
break_block: break_block,
};
self.loop_scopes.push(loop_scope);
let r = f(self);
assert!(self.loop_scopes.pop().unwrap().extent == extent);
@ -128,12 +130,8 @@ impl<'a,'tcx> Builder<'a,'tcx> {
/// Start a scope. The closure `f` should translate the contents
/// of the scope. See module comment for more details.
pub fn in_scope<F,R>(&mut self,
extent: CodeExtent,
block: BasicBlock,
f: F)
-> BlockAnd<R>
where F: FnOnce(&mut Builder<'a,'tcx>) -> BlockAnd<R>
pub fn in_scope<F, R>(&mut self, extent: CodeExtent, block: BasicBlock, f: F) -> BlockAnd<R>
where F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd<R>
{
debug!("in_scope(extent={:?}, block={:?})", extent, block);
@ -173,9 +171,15 @@ impl<'a,'tcx> Builder<'a,'tcx> {
/// exit points.
fn graph_extent(&self, entry: ExecutionPoint, exits: Vec<ExecutionPoint>) -> GraphExtent {
if exits.len() == 1 && entry.block == exits[0].block {
GraphExtent { entry: entry, exit: GraphExtentExit::Statement(exits[0].statement) }
GraphExtent {
entry: entry,
exit: GraphExtentExit::Statement(exits[0].statement),
}
} else {
GraphExtent { entry: entry, exit: GraphExtentExit::Points(exits) }
GraphExtent {
entry: entry,
exit: GraphExtentExit::Points(exits),
}
}
}
@ -204,7 +208,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
match loop_scope {
Some(loop_scope) => loop_scope.clone(),
None => self.hir.span_bug(span, "no enclosing loop scope found?")
None => self.hir.span_bug(span, "no enclosing loop scope found?"),
}
}
@ -255,8 +259,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
extent: CodeExtent,
kind: DropKind,
lvalue: &Lvalue<'tcx>,
lvalue_ty: Ty<'tcx>)
{
lvalue_ty: Ty<'tcx>) {
if self.hir.needs_drop(lvalue_ty, span) {
match self.scopes.iter_mut().rev().find(|s| s.extent == extent) {
Some(scope) => {
@ -278,9 +281,7 @@ impl<'a,'tcx> Builder<'a,'tcx> {
}
}
fn diverge_cleanup_helper<'tcx>(cfg: &mut CFG<'tcx>,
scopes: &mut [Scope<'tcx>])
-> BasicBlock {
fn diverge_cleanup_helper<'tcx>(cfg: &mut CFG<'tcx>, scopes: &mut [Scope<'tcx>]) -> BasicBlock {
let len = scopes.len();
if len == 0 {

View File

@ -70,15 +70,18 @@ impl<'a,'tcx> dot::GraphWalk<'a, BasicBlock, EdgeIndex> for Mir<'tcx> {
self.all_basic_blocks()
.into_iter()
.flat_map(|source| {
self.basic_block_data(source).terminator
.successors()
.iter()
.enumerate()
.map(move |(index, &target)| {
EdgeIndex { source: source,
target: target,
index: index }
})
self.basic_block_data(source)
.terminator
.successors()
.iter()
.enumerate()
.map(move |(index, &target)| {
EdgeIndex {
source: source,
target: target,
index: index,
}
})
})
.collect::<Vec<_>>()
.into_cow()
@ -118,7 +121,10 @@ fn all_to_subscript(header: &str, mut text: String) -> String {
/// Returns an updated string if changes were made, else None.
fn to_subscript1(header: &str, text: &str, offset: &mut usize) -> Option<String> {
let a = match text[*offset..].find(header) {
None => { *offset = text.len(); return None; }
None => {
*offset = text.len();
return None;
}
Some(a) => a + *offset,
};
@ -141,8 +147,12 @@ fn all_to_subscript(header: &str, mut text: String) -> String {
result.push_str(&text[..b]);
while let Some(c) = chars.next() {
if c == ')' { break; }
if !c.is_digit(10) { return None; }
if c == ')' {
break;
}
if !c.is_digit(10) {
return None;
}
// 0x208 is _0 in unicode, 0x209 is _1, etc
const SUBSCRIPTS: &'static str = "₀₁₂₃₄₅₆₇₈₉";

View File

@ -58,7 +58,7 @@ pub enum StmtKind<'tcx> {
scope: CodeExtent,
/// expression being evaluated in this statement
expr: ExprRef<'tcx>
expr: ExprRef<'tcx>,
},
Let {
@ -77,7 +77,7 @@ pub enum StmtKind<'tcx> {
initializer: Option<ExprRef<'tcx>>,
/// let pat = init; <STMTS>
stmts: Vec<StmtRef<'tcx>>
stmts: Vec<StmtRef<'tcx>>,
},
}
@ -113,45 +113,128 @@ pub struct Expr<'tcx> {
#[derive(Clone, Debug)]
pub enum ExprKind<'tcx> {
Scope { extent: CodeExtent, value: ExprRef<'tcx> },
Box { value: ExprRef<'tcx> },
Call { fun: ExprRef<'tcx>, args: Vec<ExprRef<'tcx>> },
Deref { arg: ExprRef<'tcx> }, // NOT overloaded!
Binary { op: BinOp, lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx> }, // NOT overloaded!
LogicalOp { op: LogicalOp, lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx> },
Unary { op: UnOp, arg: ExprRef<'tcx> }, // NOT overloaded!
Cast { source: ExprRef<'tcx> },
ReifyFnPointer { source: ExprRef<'tcx> },
UnsafeFnPointer { source: ExprRef<'tcx> },
Unsize { source: ExprRef<'tcx> },
If { condition: ExprRef<'tcx>, then: ExprRef<'tcx>, otherwise: Option<ExprRef<'tcx>> },
Loop { condition: Option<ExprRef<'tcx>>, body: ExprRef<'tcx>, },
Match { discriminant: ExprRef<'tcx>, arms: Vec<Arm<'tcx>> },
Block { body: &'tcx hir::Block },
Assign { lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx> },
AssignOp { op: BinOp, lhs: ExprRef<'tcx>, rhs: ExprRef<'tcx> },
Field { lhs: ExprRef<'tcx>, name: Field },
Index { lhs: ExprRef<'tcx>, index: ExprRef<'tcx> },
VarRef { id: ast::NodeId },
Scope {
extent: CodeExtent,
value: ExprRef<'tcx>,
},
Box {
value: ExprRef<'tcx>,
},
Call {
fun: ExprRef<'tcx>,
args: Vec<ExprRef<'tcx>>,
},
Deref {
arg: ExprRef<'tcx>,
}, // NOT overloaded!
Binary {
op: BinOp,
lhs: ExprRef<'tcx>,
rhs: ExprRef<'tcx>,
}, // NOT overloaded!
LogicalOp {
op: LogicalOp,
lhs: ExprRef<'tcx>,
rhs: ExprRef<'tcx>,
},
Unary {
op: UnOp,
arg: ExprRef<'tcx>,
}, // NOT overloaded!
Cast {
source: ExprRef<'tcx>,
},
ReifyFnPointer {
source: ExprRef<'tcx>,
},
UnsafeFnPointer {
source: ExprRef<'tcx>,
},
Unsize {
source: ExprRef<'tcx>,
},
If {
condition: ExprRef<'tcx>,
then: ExprRef<'tcx>,
otherwise: Option<ExprRef<'tcx>>,
},
Loop {
condition: Option<ExprRef<'tcx>>,
body: ExprRef<'tcx>,
},
Match {
discriminant: ExprRef<'tcx>,
arms: Vec<Arm<'tcx>>,
},
Block {
body: &'tcx hir::Block,
},
Assign {
lhs: ExprRef<'tcx>,
rhs: ExprRef<'tcx>,
},
AssignOp {
op: BinOp,
lhs: ExprRef<'tcx>,
rhs: ExprRef<'tcx>,
},
Field {
lhs: ExprRef<'tcx>,
name: Field,
},
Index {
lhs: ExprRef<'tcx>,
index: ExprRef<'tcx>,
},
VarRef {
id: ast::NodeId,
},
SelfRef, // first argument, used for self in a closure
StaticRef { id: DefId },
Borrow { region: Region, borrow_kind: BorrowKind, arg: ExprRef<'tcx> },
Break { label: Option<CodeExtent> },
Continue { label: Option<CodeExtent> },
Return { value: Option<ExprRef<'tcx>> },
Repeat { value: ExprRef<'tcx>, count: ExprRef<'tcx> },
Vec { fields: Vec<ExprRef<'tcx>> },
Tuple { fields: Vec<ExprRef<'tcx>> },
Adt { adt_def: AdtDef<'tcx>,
variant_index: usize,
substs: &'tcx Substs<'tcx>,
fields: Vec<FieldExprRef<'tcx>>,
base: Option<ExprRef<'tcx>> },
Closure { closure_id: DefId,
substs: &'tcx ClosureSubsts<'tcx>,
upvars: Vec<ExprRef<'tcx>> },
Literal { literal: Literal<'tcx> },
InlineAsm { asm: &'tcx hir::InlineAsm },
StaticRef {
id: DefId,
},
Borrow {
region: Region,
borrow_kind: BorrowKind,
arg: ExprRef<'tcx>,
},
Break {
label: Option<CodeExtent>,
},
Continue {
label: Option<CodeExtent>,
},
Return {
value: Option<ExprRef<'tcx>>,
},
Repeat {
value: ExprRef<'tcx>,
count: ExprRef<'tcx>,
},
Vec {
fields: Vec<ExprRef<'tcx>>,
},
Tuple {
fields: Vec<ExprRef<'tcx>>,
},
Adt {
adt_def: AdtDef<'tcx>,
variant_index: usize,
substs: &'tcx Substs<'tcx>,
fields: Vec<FieldExprRef<'tcx>>,
base: Option<ExprRef<'tcx>>,
},
Closure {
closure_id: DefId,
substs: &'tcx ClosureSubsts<'tcx>,
upvars: Vec<ExprRef<'tcx>>,
},
Literal {
literal: Literal<'tcx>,
},
InlineAsm {
asm: &'tcx hir::InlineAsm,
},
}
#[derive(Clone, Debug)]
@ -183,7 +266,7 @@ pub struct Pattern<'tcx> {
#[derive(Copy, Clone, Debug)]
pub enum LogicalOp {
And,
Or
Or,
}
#[derive(Clone, Debug)]
@ -191,36 +274,53 @@ pub enum PatternKind<'tcx> {
Wild,
// x, ref x, x @ P, etc
Binding { mutability: Mutability,
name: ast::Name,
mode: BindingMode,
var: ast::NodeId,
ty: Ty<'tcx>,
subpattern: Option<PatternRef<'tcx>> },
Binding {
mutability: Mutability,
name: ast::Name,
mode: BindingMode,
var: ast::NodeId,
ty: Ty<'tcx>,
subpattern: Option<PatternRef<'tcx>>,
},
// Foo(...) or Foo{...} or Foo, where `Foo` is a variant name from an adt with >1 variants
Variant { adt_def: AdtDef<'tcx>,
variant_index: usize,
subpatterns: Vec<FieldPatternRef<'tcx>> },
Variant {
adt_def: AdtDef<'tcx>,
variant_index: usize,
subpatterns: Vec<FieldPatternRef<'tcx>>,
},
// (...), Foo(...), Foo{...}, or Foo, where `Foo` is a variant name from an adt with 1 variant
Leaf { subpatterns: Vec<FieldPatternRef<'tcx>> },
Leaf {
subpatterns: Vec<FieldPatternRef<'tcx>>,
},
Deref { subpattern: PatternRef<'tcx> }, // box P, &P, &mut P, etc
Deref {
subpattern: PatternRef<'tcx>,
}, // box P, &P, &mut P, etc
Constant { value: Literal<'tcx> },
Constant {
value: Literal<'tcx>,
},
Range { lo: Literal<'tcx>, hi: Literal<'tcx> },
Range {
lo: Literal<'tcx>,
hi: Literal<'tcx>,
},
// matches against a slice, checking the length and extracting elements
Slice { prefix: Vec<PatternRef<'tcx>>,
slice: Option<PatternRef<'tcx>>,
suffix: Vec<PatternRef<'tcx>> },
Slice {
prefix: Vec<PatternRef<'tcx>>,
slice: Option<PatternRef<'tcx>>,
suffix: Vec<PatternRef<'tcx>>,
},
// fixed match against an array, irrefutable
Array { prefix: Vec<PatternRef<'tcx>>,
slice: Option<PatternRef<'tcx>>,
suffix: Vec<PatternRef<'tcx>> },
Array {
prefix: Vec<PatternRef<'tcx>>,
slice: Option<PatternRef<'tcx>>,
suffix: Vec<PatternRef<'tcx>>,
},
}
#[derive(Copy, Clone, Debug)]
@ -259,13 +359,13 @@ pub struct FieldPatternRef<'tcx> {
pub trait Mirror<'tcx> {
type Output;
fn make_mirror<'a>(self, cx: &mut Cx<'a,'tcx>) -> Self::Output;
fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Self::Output;
}
impl<'tcx> Mirror<'tcx> for Expr<'tcx> {
type Output = Expr<'tcx>;
fn make_mirror<'a>(self, _: &mut Cx<'a,'tcx>) -> Expr<'tcx> {
fn make_mirror<'a>(self, _: &mut Cx<'a, 'tcx>) -> Expr<'tcx> {
self
}
}
@ -273,7 +373,7 @@ impl<'tcx> Mirror<'tcx> for Expr<'tcx> {
impl<'tcx> Mirror<'tcx> for ExprRef<'tcx> {
type Output = Expr<'tcx>;
fn make_mirror<'a>(self, hir: &mut Cx<'a,'tcx>) -> Expr<'tcx> {
fn make_mirror<'a>(self, hir: &mut Cx<'a, 'tcx>) -> Expr<'tcx> {
match self {
ExprRef::Hair(h) => h.make_mirror(hir),
ExprRef::Mirror(m) => *m,
@ -284,7 +384,7 @@ impl<'tcx> Mirror<'tcx> for ExprRef<'tcx> {
impl<'tcx> Mirror<'tcx> for Stmt<'tcx> {
type Output = Stmt<'tcx>;
fn make_mirror<'a>(self, _: &mut Cx<'a,'tcx>) -> Stmt<'tcx> {
fn make_mirror<'a>(self, _: &mut Cx<'a, 'tcx>) -> Stmt<'tcx> {
self
}
}
@ -292,7 +392,7 @@ impl<'tcx> Mirror<'tcx> for Stmt<'tcx> {
impl<'tcx> Mirror<'tcx> for StmtRef<'tcx> {
type Output = Stmt<'tcx>;
fn make_mirror<'a>(self, hir: &mut Cx<'a,'tcx>) -> Stmt<'tcx> {
fn make_mirror<'a>(self, hir: &mut Cx<'a, 'tcx>) -> Stmt<'tcx> {
match self {
StmtRef::Hair(h) => h.make_mirror(hir),
StmtRef::Mirror(m) => *m,
@ -303,7 +403,7 @@ impl<'tcx> Mirror<'tcx> for StmtRef<'tcx> {
impl<'tcx> Mirror<'tcx> for Pattern<'tcx> {
type Output = Pattern<'tcx>;
fn make_mirror<'a>(self, _: &mut Cx<'a,'tcx>) -> Pattern<'tcx> {
fn make_mirror<'a>(self, _: &mut Cx<'a, 'tcx>) -> Pattern<'tcx> {
self
}
}
@ -311,7 +411,7 @@ impl<'tcx> Mirror<'tcx> for Pattern<'tcx> {
impl<'tcx> Mirror<'tcx> for PatternRef<'tcx> {
type Output = Pattern<'tcx>;
fn make_mirror<'a>(self, hir: &mut Cx<'a,'tcx>) -> Pattern<'tcx> {
fn make_mirror<'a>(self, hir: &mut Cx<'a, 'tcx>) -> Pattern<'tcx> {
match self {
PatternRef::Hair(h) => h.make_mirror(hir),
PatternRef::Mirror(m) => *m,
@ -322,8 +422,7 @@ impl<'tcx> Mirror<'tcx> for PatternRef<'tcx> {
impl<'tcx> Mirror<'tcx> for Block<'tcx> {
type Output = Block<'tcx>;
fn make_mirror<'a>(self, _: &mut Cx<'a,'tcx>) -> Block<'tcx> {
fn make_mirror<'a>(self, _: &mut Cx<'a, 'tcx>) -> Block<'tcx> {
self
}
}

View File

@ -39,10 +39,13 @@ use self::syntax::codemap::Span;
pub type MirMap<'tcx> = NodeMap<Mir<'tcx>>;
pub fn build_mir_for_crate<'tcx>(tcx: &ty::ctxt<'tcx>) -> MirMap<'tcx>{
pub fn build_mir_for_crate<'tcx>(tcx: &ty::ctxt<'tcx>) -> MirMap<'tcx> {
let mut map = NodeMap();
{
let mut dump = OuterDump { tcx: tcx, map: &mut map };
let mut dump = OuterDump {
tcx: tcx,
map: &mut map,
};
visit::walk_crate(&mut dump, tcx.map.krate());
}
map
@ -51,16 +54,20 @@ pub fn build_mir_for_crate<'tcx>(tcx: &ty::ctxt<'tcx>) -> MirMap<'tcx>{
///////////////////////////////////////////////////////////////////////////
// OuterDump -- walks a crate, looking for fn items and methods to build MIR from
struct OuterDump<'a,'tcx:'a> {
struct OuterDump<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
map: &'a mut MirMap<'tcx>,
}
impl<'a, 'tcx> OuterDump<'a, 'tcx> {
fn visit_mir<OP>(&mut self, attributes: &'a [ast::Attribute], mut walk_op: OP)
where OP: for<'m> FnMut(&mut InnerDump<'a,'m,'tcx>)
where OP: for<'m> FnMut(&mut InnerDump<'a, 'm, 'tcx>)
{
let mut closure_dump = InnerDump { tcx: self.tcx, attr: None, map: &mut *self.map };
let mut closure_dump = InnerDump {
tcx: self.tcx,
attr: None,
map: &mut *self.map,
};
for attr in attributes {
if attr.check_name("rustc_mir") {
closure_dump.attr = Some(attr);
@ -84,8 +91,7 @@ impl<'a, 'tcx> visit::Visitor<'tcx> for OuterDump<'a, 'tcx> {
}
hir::MethodTraitItem(_, None) |
hir::ConstTraitItem(..) |
hir::TypeTraitItem(..) => {
}
hir::TypeTraitItem(..) => {}
}
visit::walk_trait_item(self, trait_item);
}
@ -95,7 +101,7 @@ impl<'a, 'tcx> visit::Visitor<'tcx> for OuterDump<'a, 'tcx> {
hir::MethodImplItem(..) => {
self.visit_mir(&impl_item.attrs, |c| visit::walk_impl_item(c, impl_item));
}
hir::ConstImplItem(..) | hir::TypeImplItem(..) => { }
hir::ConstImplItem(..) | hir::TypeImplItem(..) => {}
}
visit::walk_impl_item(self, impl_item);
}
@ -104,7 +110,7 @@ impl<'a, 'tcx> visit::Visitor<'tcx> for OuterDump<'a, 'tcx> {
///////////////////////////////////////////////////////////////////////////
// InnerDump -- dumps MIR for a single fn and its contained closures
struct InnerDump<'a,'m,'tcx:'a+'m> {
struct InnerDump<'a, 'm, 'tcx: 'a + 'm> {
tcx: &'a ty::ctxt<'tcx>,
map: &'m mut MirMap<'tcx>,
attr: Option<&'a ast::Attribute>,
@ -136,21 +142,16 @@ impl<'a, 'm, 'tcx> visit::Visitor<'tcx> for InnerDump<'a,'m,'tcx> {
(format!(""), vec![]),
};
let param_env =
ty::ParameterEnvironment::for_item(self.tcx, id);
let param_env = ty::ParameterEnvironment::for_item(self.tcx, id);
let infcx =
infer::new_infer_ctxt(self.tcx,
&self.tcx.tables,
Some(param_env),
true);
let infcx = infer::new_infer_ctxt(self.tcx, &self.tcx.tables, Some(param_env), true);
match build_mir(Cx::new(&infcx), implicit_arg_tys, id, span, decl, body) {
Ok(mir) => {
let meta_item_list =
self.attr.iter()
.flat_map(|a| a.meta_item_list())
.flat_map(|l| l.iter());
let meta_item_list = self.attr
.iter()
.flat_map(|a| a.meta_item_list())
.flat_map(|l| l.iter());
for item in meta_item_list {
if item.check_name("graphviz") {
match item.value_str() {
@ -181,58 +182,49 @@ impl<'a, 'm, 'tcx> visit::Visitor<'tcx> for InnerDump<'a,'m,'tcx> {
let previous = self.map.insert(id, mir);
assert!(previous.is_none());
}
Err(ErrorReported) => { }
Err(ErrorReported) => {}
}
visit::walk_fn(self, fk, decl, body, span);
}
}
fn build_mir<'a,'tcx:'a>(cx: Cx<'a,'tcx>,
implicit_arg_tys: Vec<Ty<'tcx>>,
fn_id: ast::NodeId,
span: Span,
decl: &'tcx hir::FnDecl,
body: &'tcx hir::Block)
-> Result<Mir<'tcx>, ErrorReported> {
let arguments =
decl.inputs
.iter()
.map(|arg| {
let ty = cx.tcx().node_id_to_type(arg.id);
(ty, PatNode::irrefutable(&arg.pat))
})
.collect();
fn build_mir<'a, 'tcx: 'a>(cx: Cx<'a, 'tcx>,
implicit_arg_tys: Vec<Ty<'tcx>>,
fn_id: ast::NodeId,
span: Span,
decl: &'tcx hir::FnDecl,
body: &'tcx hir::Block)
-> Result<Mir<'tcx>, ErrorReported> {
let arguments = decl.inputs
.iter()
.map(|arg| {
let ty = cx.tcx().node_id_to_type(arg.id);
(ty, PatNode::irrefutable(&arg.pat))
})
.collect();
let parameter_scope =
cx.tcx().region_maps.lookup_code_extent(
CodeExtentData::ParameterScope { fn_id: fn_id, body_id: body.id });
Ok(build::construct(cx,
span,
implicit_arg_tys,
arguments,
parameter_scope,
body))
let parameter_scope = cx.tcx().region_maps.lookup_code_extent(CodeExtentData::ParameterScope {
fn_id: fn_id,
body_id: body.id,
});
Ok(build::construct(cx, span, implicit_arg_tys, arguments, parameter_scope, body))
}
fn closure_self_ty<'a,'tcx>(tcx: &ty::ctxt<'tcx>,
closure_expr_id: ast::NodeId,
body_id: ast::NodeId)
-> Ty<'tcx>
{
fn closure_self_ty<'a, 'tcx>(tcx: &ty::ctxt<'tcx>,
closure_expr_id: ast::NodeId,
body_id: ast::NodeId)
-> Ty<'tcx> {
let closure_ty = tcx.node_id_to_type(closure_expr_id);
// We're just hard-coding the idea that the signature will be
// &self or &mut self and hence will have a bound region with
// number 0, hokey.
let region =
ty::Region::ReFree(
ty::FreeRegion {
scope: tcx.region_maps.item_extent(body_id),
bound_region: ty::BoundRegion::BrAnon(0)
});
let region =
tcx.mk_region(region);
let region = ty::Region::ReFree(ty::FreeRegion {
scope: tcx.region_maps.item_extent(body_id),
bound_region: ty::BoundRegion::BrAnon(0),
});
let region = tcx.mk_region(region);
match tcx.closure_kind(tcx.map.local_def_id(closure_expr_id)) {
ty::ClosureKind::FnClosureKind =>

View File

@ -110,7 +110,7 @@ pub enum BorrowKind {
Unique,
/// Data is mutable and not aliasable.
Mut
Mut,
}
///////////////////////////////////////////////////////////////////////////
@ -226,17 +226,27 @@ pub struct BasicBlockData<'tcx> {
pub enum Terminator<'tcx> {
/// block should have one successor in the graph; we jump there
Goto { target: BasicBlock },
Goto {
target: BasicBlock,
},
/// block should initiate unwinding; should be one successor
/// that does cleanup and branches to DIVERGE_BLOCK
Panic { target: BasicBlock },
Panic {
target: BasicBlock,
},
/// jump to branch 0 if this lvalue evaluates to true
If { cond: Operand<'tcx>, targets: [BasicBlock; 2] },
If {
cond: Operand<'tcx>,
targets: [BasicBlock; 2],
},
/// lvalue evaluates to some enum; jump depending on the branch
Switch { discr: Lvalue<'tcx>, targets: Vec<BasicBlock> },
Switch {
discr: Lvalue<'tcx>,
targets: Vec<BasicBlock>,
},
/// Indicates that the last statement in the block panics, aborts,
/// etc. No successors. This terminator appears on exactly one
@ -254,7 +264,10 @@ pub enum Terminator<'tcx> {
/// block ends with a call; it should have two successors. The
/// first successor indicates normal return. The second indicates
/// unwinding.
Call { data: CallData<'tcx>, targets: [BasicBlock; 2] },
Call {
data: CallData<'tcx>,
targets: [BasicBlock; 2],
},
}
impl<'tcx> Terminator<'tcx> {
@ -312,7 +325,9 @@ impl<'tcx> Debug for Terminator<'tcx> {
Call { data: ref c, targets } => {
try!(write!(fmt, "{:?} = {:?}(", c.destination, c.func));
for (index, arg) in c.args.iter().enumerate() {
if index > 0 { try!(write!(fmt, ", ")); }
if index > 0 {
try!(write!(fmt, ", "));
}
try!(write!(fmt, "{:?}", arg));
}
write!(fmt, ") -> {:?}", targets)
@ -339,7 +354,7 @@ pub enum StatementKind<'tcx> {
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum DropKind {
Shallow,
Deep
Deep,
}
impl<'tcx> Debug for Statement<'tcx> {
@ -376,7 +391,7 @@ pub enum Lvalue<'tcx> {
ReturnPointer,
/// projection out of an lvalue (access a field, deref a pointer, etc)
Projection(Box<LvalueProjection<'tcx>>)
Projection(Box<LvalueProjection<'tcx>>),
}
/// The `Projection` data structure defines things of the form `B.x`
@ -384,13 +399,13 @@ pub enum Lvalue<'tcx> {
/// shared between `Constant` and `Lvalue`. See the aliases
/// `LvalueProjection` etc below.
#[derive(Clone, Debug, PartialEq)]
pub struct Projection<'tcx,B,V> {
pub struct Projection<'tcx, B, V> {
pub base: B,
pub elem: ProjectionElem<'tcx,V>,
pub elem: ProjectionElem<'tcx, V>,
}
#[derive(Clone, Debug, PartialEq)]
pub enum ProjectionElem<'tcx,V> {
pub enum ProjectionElem<'tcx, V> {
Deref,
Field(Field),
Index(V),
@ -446,7 +461,10 @@ impl<'tcx> Lvalue<'tcx> {
}
pub fn elem(self, elem: LvalueElem<'tcx>) -> Lvalue<'tcx> {
Lvalue::Projection(Box::new(LvalueProjection { base: self, elem: elem }))
Lvalue::Projection(Box::new(LvalueProjection {
base: self,
elem: elem,
}))
}
}
@ -623,7 +641,7 @@ pub enum UnOp {
/// The `!` operator for logical inversion
Not,
/// The `-` operator for negation
Neg
Neg,
}
impl<'tcx> Debug for Rvalue<'tcx> {
@ -641,8 +659,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
Box(ref t) => write!(fmt, "Box {:?}", t),
Aggregate(ref kind, ref lvs) => write!(fmt, "Aggregate<{:?}>({:?})", kind, lvs),
InlineAsm(ref asm) => write!(fmt, "InlineAsm({:?})", asm),
Slice { ref input, from_start, from_end } => write!(fmt, "{:?}[{:?}..-{:?}]",
input, from_start, from_end),
Slice { ref input, from_start, from_end } =>
write!(fmt, "{:?}[{:?}..-{:?}]", input, from_start, from_end),
}
}
}
@ -658,12 +676,16 @@ impl<'tcx> Debug for Rvalue<'tcx> {
pub struct Constant<'tcx> {
pub span: Span,
pub ty: Ty<'tcx>,
pub literal: Literal<'tcx>
pub literal: Literal<'tcx>,
}
#[derive(Clone, Debug, PartialEq)]
pub enum Literal<'tcx> {
Item { def_id: DefId, substs: &'tcx Substs<'tcx> },
Value { value: ConstVal },
Item {
def_id: DefId,
substs: &'tcx Substs<'tcx>,
},
Value {
value: ConstVal,
},
}

View File

@ -21,7 +21,7 @@ use syntax::ptr::P;
impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
type Output = Block<'tcx>;
fn make_mirror<'a>(self, cx: &mut Cx<'a,'tcx>) -> Block<'tcx> {
fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Block<'tcx> {
// We have to eagerly translate the "spine" of the statements
// in order to get the lexical scoping correctly.
let stmts = mirror_stmts(cx, self.id, self.stmts.iter().enumerate());
@ -29,7 +29,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
extent: cx.tcx.region_maps.node_extent(self.id),
span: self.span,
stmts: stmts,
expr: self.expr.to_ref()
expr: self.expr.to_ref(),
}
}
}
@ -37,7 +37,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Block {
impl<'tcx> Mirror<'tcx> for &'tcx hir::Stmt {
type Output = Stmt<'tcx>;
fn make_mirror<'a>(self, _cx: &mut Cx<'a,'tcx>) -> Stmt<'tcx> {
fn make_mirror<'a>(self, _cx: &mut Cx<'a, 'tcx>) -> Stmt<'tcx> {
// In order to get the scoping correct, we eagerly mirror
// statements when we translate the enclosing block, so we
// should in fact never get to this point.
@ -45,11 +45,11 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Stmt {
}
}
fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>,
block_id: ast::NodeId,
mut stmts: STMTS)
-> Vec<StmtRef<'tcx>>
where STMTS: Iterator<Item=(usize, &'tcx P<hir::Stmt>)>
fn mirror_stmts<'a, 'tcx: 'a, STMTS>(cx: &mut Cx<'a, 'tcx>,
block_id: ast::NodeId,
mut stmts: STMTS)
-> Vec<StmtRef<'tcx>>
where STMTS: Iterator<Item = (usize, &'tcx P<hir::Stmt>)>
{
let mut result = vec![];
while let Some((index, stmt)) = stmts.next() {
@ -68,7 +68,7 @@ fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>,
hir::DeclLocal(ref local) => {
let remainder_extent = CodeExtentData::Remainder(BlockRemainder {
block: block_id,
first_statement_index: index as u32
first_statement_index: index as u32,
});
let remainder_extent =
cx.tcx.region_maps.lookup_code_extent(remainder_extent);
@ -77,18 +77,16 @@ fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>,
// they are within the scope of this let:
let following_stmts = mirror_stmts(cx, block_id, stmts);
result.push(
StmtRef::Mirror(
Box::new(Stmt {
span: stmt.span,
kind: StmtKind::Let {
remainder_scope: remainder_extent,
init_scope: cx.tcx.region_maps.node_extent(id),
pattern: PatNode::irrefutable(&local.pat).to_ref(),
initializer: local.init.to_ref(),
stmts: following_stmts
}
})));
result.push(StmtRef::Mirror(Box::new(Stmt {
span: stmt.span,
kind: StmtKind::Let {
remainder_scope: remainder_extent,
init_scope: cx.tcx.region_maps.node_extent(id),
pattern: PatNode::irrefutable(&local.pat).to_ref(),
initializer: local.init.to_ref(),
stmts: following_stmts,
},
})));
return result;
}
@ -99,16 +97,14 @@ fn mirror_stmts<'a,'tcx:'a,STMTS>(cx: &mut Cx<'a,'tcx>,
return result;
}
pub fn to_expr_ref<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
block: &'tcx hir::Block)
-> ExprRef<'tcx> {
pub fn to_expr_ref<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, block: &'tcx hir::Block) -> ExprRef<'tcx> {
let block_ty = cx.tcx.node_id_to_type(block.id);
let temp_lifetime = cx.tcx.region_maps.temporary_scope(block.id);
let expr = Expr {
ty: block_ty,
temp_lifetime: temp_lifetime,
span: block.span,
kind: ExprKind::Block { body: block }
kind: ExprKind::Block { body: block },
};
expr.to_ref()
}

View File

@ -30,14 +30,13 @@ use syntax::ptr::P;
impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
type Output = Expr<'tcx>;
fn make_mirror<'a>(self, cx: &mut Cx<'a,'tcx>) -> Expr<'tcx> {
fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Expr<'tcx> {
debug!("Expr::make_mirror(): id={}, span={:?}", self.id, self.span);
let expr_ty = cx.tcx.expr_ty(self); // note: no adjustments (yet)!
let kind = match self.node {
// Here comes the interesting stuff:
hir::ExprMethodCall(_, _, ref args) => {
// Rewrite a.b(c) into UFCS form like Trait::b(a, c)
let expr = method_callee(cx, self, ty::MethodCall::expr(self.id));
@ -46,24 +45,24 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
.collect();
ExprKind::Call {
fun: expr.to_ref(),
args: args
args: args,
}
}
hir::ExprAddrOf(mutbl, ref expr) => {
let region = match expr_ty.sty {
ty::TyRef(r, _) => r,
_ => cx.tcx.sess.span_bug(expr.span, "type of & not region")
_ => cx.tcx.sess.span_bug(expr.span, "type of & not region"),
};
ExprKind::Borrow { region: *region,
borrow_kind: to_borrow_kind(mutbl),
arg: expr.to_ref() }
ExprKind::Borrow {
region: *region,
borrow_kind: to_borrow_kind(mutbl),
arg: expr.to_ref(),
}
}
hir::ExprBlock(ref blk) => {
ExprKind::Block {
body: &**blk
}
ExprKind::Block { body: &**blk }
}
hir::ExprAssign(ref lhs, ref rhs) => {
@ -100,20 +99,26 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
// FIXME overflow
match op.node {
hir::BinOp_::BiAnd => {
ExprKind::LogicalOp { op: LogicalOp::And,
lhs: lhs.to_ref(),
rhs: rhs.to_ref() }
ExprKind::LogicalOp {
op: LogicalOp::And,
lhs: lhs.to_ref(),
rhs: rhs.to_ref(),
}
}
hir::BinOp_::BiOr => {
ExprKind::LogicalOp { op: LogicalOp::Or,
lhs: lhs.to_ref(),
rhs: rhs.to_ref() }
ExprKind::LogicalOp {
op: LogicalOp::Or,
lhs: lhs.to_ref(),
rhs: rhs.to_ref(),
}
}
_ => {
let op = bin_op(op.node);
ExprKind::Binary { op: op,
lhs: lhs.to_ref(),
rhs: rhs.to_ref() }
ExprKind::Binary {
op: op,
lhs: lhs.to_ref(),
rhs: rhs.to_ref(),
}
}
}
}
@ -124,8 +129,10 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
overloaded_lvalue(cx, self, ty::MethodCall::expr(self.id),
PassArgs::ByValue, lhs.to_ref(), vec![index])
} else {
ExprKind::Index { lhs: lhs.to_ref(),
index: index.to_ref() }
ExprKind::Index {
lhs: lhs.to_ref(),
index: index.to_ref(),
}
}
}
@ -153,7 +160,10 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
"UnDeref should have been handled elsewhere");
}
};
ExprKind::Unary { op: op, arg: arg.to_ref() }
ExprKind::Unary {
op: op,
arg: arg.to_ref(),
}
}
}
@ -202,8 +212,8 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
ty::TyClosure(def_id, ref substs) => (def_id, substs),
_ => {
cx.tcx.sess.span_bug(self.span,
&format!("closure expr w/o closure type: {:?}",
closure_ty));
&format!("closure expr w/o closure type: {:?}",
closure_ty));
}
};
let upvars = cx.tcx.with_freevars(self.id, |freevars| {
@ -224,15 +234,15 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
let (adt_def, substs) = match range_ty.sty {
ty::TyStruct(adt_def, substs) => (adt_def, substs),
_ => {
cx.tcx.sess.span_bug(
self.span,
&format!("unexpanded ast"));
cx.tcx.sess.span_bug(self.span, &format!("unexpanded ast"));
}
};
let field_expr_ref = |s: &'tcx P<hir::Expr>, nm: &str| {
FieldExprRef { name: Field::Named(token::intern(nm)),
expr: s.to_ref() }
FieldExprRef {
name: Field::Named(token::intern(nm)),
expr: s.to_ref(),
}
};
let start_field = start.as_ref()
@ -243,11 +253,13 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
.into_iter()
.map(|e| field_expr_ref(e, "end"));
ExprKind::Adt { adt_def: adt_def,
variant_index: 0,
substs: substs,
fields: start_field.chain(end_field).collect(),
base: None }
ExprKind::Adt {
adt_def: adt_def,
variant_index: 0,
substs: substs,
fields: start_field.chain(end_field).collect(),
base: None,
}
}
hir::ExprPath(..) => {
@ -311,7 +323,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
// Now apply adjustments, if any.
match cx.tcx.tables.borrow().adjustments.get(&self.id) {
None => { }
None => {}
Some(&ty::adjustment::AdjustReifyFnPointer) => {
let adjusted_ty = cx.tcx.expr_ty_adjusted(self);
expr = Expr {
@ -350,7 +362,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
temp_lifetime: temp_lifetime,
ty: adjusted_ty,
span: self.span,
kind: kind
kind: kind,
};
}
@ -359,7 +371,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
temp_lifetime: temp_lifetime,
ty: target,
span: self.span,
kind: ExprKind::Unsize { source: expr.to_ref() }
kind: ExprKind::Unsize { source: expr.to_ref() },
};
} else if let Some(autoref) = adj.autoref {
let adjusted_ty = expr.ty.adjust_for_autoref(cx.tcx, Some(autoref));
@ -369,9 +381,11 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
temp_lifetime: temp_lifetime,
ty: adjusted_ty,
span: self.span,
kind: ExprKind::Borrow { region: *r,
borrow_kind: to_borrow_kind(m),
arg: expr.to_ref() }
kind: ExprKind::Borrow {
region: *r,
borrow_kind: to_borrow_kind(m),
arg: expr.to_ref(),
},
};
}
ty::adjustment::AutoUnsafe(m) => {
@ -384,15 +398,17 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
temp_lifetime: temp_lifetime,
ty: cx.tcx.mk_ref(region, ty::TypeAndMut { ty: expr.ty, mutbl: m }),
span: self.span,
kind: ExprKind::Borrow { region: *region,
borrow_kind: to_borrow_kind(m),
arg: expr.to_ref() }
kind: ExprKind::Borrow {
region: *region,
borrow_kind: to_borrow_kind(m),
arg: expr.to_ref(),
},
};
expr = Expr {
temp_lifetime: temp_lifetime,
ty: adjusted_ty,
span: self.span,
kind: ExprKind::Cast { source: expr.to_ref() }
kind: ExprKind::Cast { source: expr.to_ref() },
};
}
}
@ -405,8 +421,10 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
temp_lifetime: temp_lifetime,
ty: expr.ty,
span: self.span,
kind: ExprKind::Scope { extent: expr_extent,
value: expr.to_ref() }
kind: ExprKind::Scope {
extent: expr_extent,
value: expr.to_ref(),
},
};
// Finally, create a destruction scope, if any.
@ -415,7 +433,10 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
temp_lifetime: temp_lifetime,
ty: expr.ty,
span: self.span,
kind: ExprKind::Scope { extent: extent, value: expr.to_ref() }
kind: ExprKind::Scope {
extent: extent,
value: expr.to_ref(),
},
};
}
@ -424,10 +445,10 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
}
}
fn method_callee<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
expr: &hir::Expr,
method_call: ty::MethodCall)
-> Expr<'tcx> {
fn method_callee<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>,
expr: &hir::Expr,
method_call: ty::MethodCall)
-> Expr<'tcx> {
let tables = cx.tcx.tables.borrow();
let callee = &tables.method_map[&method_call];
let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id);
@ -439,8 +460,8 @@ fn method_callee<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
literal: Literal::Item {
def_id: callee.def_id,
substs: callee.substs,
}
}
},
},
}
}
@ -451,7 +472,7 @@ fn to_borrow_kind(m: hir::Mutability) -> BorrowKind {
}
}
fn convert_arm<'a,'tcx:'a>(cx: &Cx<'a,'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
fn convert_arm<'a, 'tcx: 'a>(cx: &Cx<'a, 'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
let map = if arm.pats.len() == 1 {
None
} else {
@ -462,15 +483,14 @@ fn convert_arm<'a,'tcx:'a>(cx: &Cx<'a,'tcx>, arm: &'tcx hir::Arm) -> Arm<'tcx> {
Some(Rc::new(map))
};
Arm { patterns: arm.pats.iter().map(|p| PatNode::new(p, map.clone()).to_ref()).collect(),
guard: arm.guard.to_ref(),
body: arm.body.to_ref() }
Arm {
patterns: arm.pats.iter().map(|p| PatNode::new(p, map.clone()).to_ref()).collect(),
guard: arm.guard.to_ref(),
body: arm.body.to_ref(),
}
}
fn convert_path_expr<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
expr: &'tcx hir::Expr)
-> ExprKind<'tcx>
{
fn convert_path_expr<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr) -> ExprKind<'tcx> {
let substs = cx.tcx.mk_substs(cx.tcx.node_id_item_substs(expr.id).substs);
match cx.tcx.def_map.borrow()[&expr.id].full_def() {
def::DefVariant(_, def_id, false) |
@ -499,11 +519,10 @@ fn convert_path_expr<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
}
}
fn convert_var<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
expr: &'tcx hir::Expr,
def: def::Def)
-> ExprKind<'tcx>
{
fn convert_var<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>,
expr: &'tcx hir::Expr,
def: def::Def)
-> ExprKind<'tcx> {
let temp_lifetime = cx.tcx.region_maps.temporary_scope(expr.id);
match def {
@ -534,20 +553,16 @@ fn convert_var<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
};
// FIXME free regions in closures are not right
let closure_ty =
cx.tcx.node_id_to_type(closure_expr_id);
let closure_ty = cx.tcx.node_id_to_type(closure_expr_id);
// FIXME we're just hard-coding the idea that the
// signature will be &self or &mut self and hence will
// have a bound region with number 0
let region =
ty::Region::ReFree(
ty::FreeRegion {
scope: cx.tcx.region_maps.node_extent(body_id),
bound_region: ty::BoundRegion::BrAnon(0)
});
let region =
cx.tcx.mk_region(region);
let region = ty::Region::ReFree(ty::FreeRegion {
scope: cx.tcx.region_maps.node_extent(body_id),
bound_region: ty::BoundRegion::BrAnon(0),
});
let region = cx.tcx.mk_region(region);
let self_expr = match cx.tcx.closure_kind(cx.tcx.map.local_def_id(closure_expr_id)) {
ty::ClosureKind::FnClosureKind => {
@ -593,19 +608,23 @@ fn convert_var<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
ty: closure_ty,
temp_lifetime: temp_lifetime,
span: expr.span,
kind: ExprKind::SelfRef
kind: ExprKind::SelfRef,
}
}
};
// at this point we have `self.n`, which loads up the upvar
let field_kind =
ExprKind::Field { lhs: self_expr.to_ref(),
name: Field::Indexed(index) };
let field_kind = ExprKind::Field {
lhs: self_expr.to_ref(),
name: Field::Indexed(index),
};
// ...but the upvar might be an `&T` or `&mut T` capture, at which
// point we need an implicit deref
let upvar_id = ty::UpvarId { var_id: id_var, closure_expr_id: closure_expr_id };
let upvar_id = ty::UpvarId {
var_id: id_var,
closure_expr_id: closure_expr_id,
};
let upvar_capture = match cx.tcx.upvar_capture(upvar_id) {
Some(c) => c,
None => {
@ -629,7 +648,7 @@ fn convert_var<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
}
}
_ => cx.tcx.sess.span_bug(expr.span, "type of & not region")
_ => cx.tcx.sess.span_bug(expr.span, "type of & not region"),
}
}
@ -652,23 +671,22 @@ fn bin_op(op: hir::BinOp_) -> BinOp {
hir::BinOp_::BiNe => BinOp::Ne,
hir::BinOp_::BiGe => BinOp::Ge,
hir::BinOp_::BiGt => BinOp::Gt,
_ => panic!("no equivalent for ast binop {:?}", op)
_ => panic!("no equivalent for ast binop {:?}", op),
}
}
enum PassArgs {
ByValue,
ByRef
ByRef,
}
fn overloaded_operator<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
expr: &'tcx hir::Expr,
method_call: ty::MethodCall,
pass_args: PassArgs,
receiver: ExprRef<'tcx>,
args: Vec<&'tcx P<hir::Expr>>)
-> ExprKind<'tcx>
{
fn overloaded_operator<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>,
expr: &'tcx hir::Expr,
method_call: ty::MethodCall,
pass_args: PassArgs,
receiver: ExprRef<'tcx>,
args: Vec<&'tcx P<hir::Expr>>)
-> ExprKind<'tcx> {
// the receiver has all the adjustments that are needed, so we can
// just push a reference to it
let mut argrefs = vec![receiver];
@ -677,9 +695,7 @@ fn overloaded_operator<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
// operator, we have to gin up the autorefs (but by value is easy)
match pass_args {
PassArgs::ByValue => {
argrefs.extend(
args.iter()
.map(|arg| arg.to_ref()))
argrefs.extend(args.iter().map(|arg| arg.to_ref()))
}
PassArgs::ByRef => {
@ -714,14 +730,13 @@ fn overloaded_operator<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
}
}
fn overloaded_lvalue<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
expr: &'tcx hir::Expr,
method_call: ty::MethodCall,
pass_args: PassArgs,
receiver: ExprRef<'tcx>,
args: Vec<&'tcx P<hir::Expr>>)
-> ExprKind<'tcx>
{
fn overloaded_lvalue<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>,
expr: &'tcx hir::Expr,
method_call: ty::MethodCall,
pass_args: PassArgs,
receiver: ExprRef<'tcx>,
args: Vec<&'tcx P<hir::Expr>>)
-> ExprKind<'tcx> {
// For an overloaded *x or x[y] expression of type T, the method
// call returns an &T and we must add the deref so that the types
// line up (this is because `*x` and `x[y]` represent lvalues):
@ -750,20 +765,25 @@ fn overloaded_lvalue<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
ExprKind::Deref { arg: ref_expr.to_ref() }
}
fn capture_freevar<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
closure_expr: &'tcx hir::Expr,
freevar: &ty::Freevar,
freevar_ty: Ty<'tcx>)
-> ExprRef<'tcx> {
fn capture_freevar<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>,
closure_expr: &'tcx hir::Expr,
freevar: &ty::Freevar,
freevar_ty: Ty<'tcx>)
-> ExprRef<'tcx> {
let id_var = freevar.def.var_id();
let upvar_id = ty::UpvarId { var_id: id_var, closure_expr_id: closure_expr.id };
let upvar_id = ty::UpvarId {
var_id: id_var,
closure_expr_id: closure_expr.id,
};
let upvar_capture = cx.tcx.upvar_capture(upvar_id).unwrap();
let temp_lifetime = cx.tcx.region_maps.temporary_scope(closure_expr.id);
let var_ty = cx.tcx.node_id_to_type(id_var);
let captured_var = Expr { temp_lifetime: temp_lifetime,
ty: var_ty,
span: closure_expr.span,
kind: convert_var(cx, closure_expr, freevar.def) };
let captured_var = Expr {
temp_lifetime: temp_lifetime,
ty: var_ty,
span: closure_expr.span,
kind: convert_var(cx, closure_expr, freevar.def),
};
match upvar_capture {
ty::UpvarCapture::ByValue => {
captured_var.to_ref()
@ -786,16 +806,11 @@ fn capture_freevar<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
}
}
fn loop_label<'a,'tcx:'a>(cx: &mut Cx<'a,'tcx>,
expr: &'tcx hir::Expr)
-> CodeExtent
{
fn loop_label<'a, 'tcx: 'a>(cx: &mut Cx<'a, 'tcx>, expr: &'tcx hir::Expr) -> CodeExtent {
match cx.tcx.def_map.borrow().get(&expr.id).map(|d| d.full_def()) {
Some(def::DefLabel(loop_id)) => cx.tcx.region_maps.node_extent(loop_id),
d => {
cx.tcx.sess.span_bug(
expr.span,
&format!("loop scope resolved to {:?}", d));
cx.tcx.sess.span_bug(expr.span, &format!("loop scope resolved to {:?}", d));
}
}
}

View File

@ -27,14 +27,17 @@ use syntax::codemap::Span;
use syntax::parse::token::{self, special_idents};
#[derive(Copy, Clone)]
pub struct Cx<'a,'tcx:'a> {
pub struct Cx<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
infcx: &'a InferCtxt<'a,'tcx>,
infcx: &'a InferCtxt<'a, 'tcx>,
}
impl<'a,'tcx> Cx<'a,'tcx> {
pub fn new(infcx: &'a InferCtxt<'a,'tcx>) -> Cx<'a,'tcx> {
Cx { tcx: infcx.tcx, infcx: infcx }
pub fn new(infcx: &'a InferCtxt<'a, 'tcx>) -> Cx<'a, 'tcx> {
Cx {
tcx: infcx.tcx,
infcx: infcx,
}
}
}
@ -42,7 +45,7 @@ pub use self::pattern::PatNode;
impl<'a,'tcx:'a> Cx<'a, 'tcx> {
/// Normalizes `ast` into the appropriate `mirror` type.
pub fn mirror<M:Mirror<'tcx>>(&mut self, ast: M) -> M::Output {
pub fn mirror<M: Mirror<'tcx>>(&mut self, ast: M) -> M::Output {
ast.make_mirror(self)
}
@ -141,13 +144,11 @@ impl<'a,'tcx:'a> Cx<'a, 'tcx> {
}
}
ty::ImplOrTraitItem::ConstTraitItem(..) |
ty::ImplOrTraitItem::TypeTraitItem(..) => {
}
ty::ImplOrTraitItem::TypeTraitItem(..) => {}
}
}
self.tcx.sess.bug(
&format!("found no method `{}` in `{:?}`", method_name, trait_def_id));
self.tcx.sess.bug(&format!("found no method `{}` in `{:?}`", method_name, trait_def_id));
}
}
@ -155,4 +156,3 @@ mod block;
mod expr;
mod pattern;
mod to_ref;

View File

@ -40,7 +40,7 @@ use syntax::ptr::P;
#[derive(Clone, Debug)]
pub struct PatNode<'tcx> {
pat: &'tcx hir::Pat,
binding_map: Option<Rc<FnvHashMap<ast::Name, ast::NodeId>>>
binding_map: Option<Rc<FnvHashMap<ast::Name, ast::NodeId>>>,
}
impl<'tcx> PatNode<'tcx> {
@ -53,8 +53,7 @@ impl<'tcx> PatNode<'tcx> {
}
}
pub fn irrefutable(pat: &'tcx hir::Pat)
-> PatNode<'tcx> {
pub fn irrefutable(pat: &'tcx hir::Pat) -> PatNode<'tcx> {
PatNode::new(pat, None)
}
@ -76,8 +75,7 @@ impl<'tcx> PatNode<'tcx> {
prefix: &'tcx Vec<P<hir::Pat>>,
slice: &'tcx Option<P<hir::Pat>>,
suffix: &'tcx Vec<P<hir::Pat>>)
-> PatternKind<'tcx>
{
-> PatternKind<'tcx> {
match ty.sty {
ty::TySlice(..) =>
// matching a slice or fixed-length array
@ -98,9 +96,7 @@ impl<'tcx> PatNode<'tcx> {
}
_ => {
cx.tcx.sess.span_bug(
self.pat.span,
"unexpanded macro or bad constant etc");
cx.tcx.sess.span_bug(self.pat.span, "unexpanded macro or bad constant etc");
}
}
}
@ -108,16 +104,17 @@ impl<'tcx> PatNode<'tcx> {
fn variant_or_leaf<'a>(&self,
cx: &mut Cx<'a, 'tcx>,
subpatterns: Vec<FieldPatternRef<'tcx>>)
-> PatternKind<'tcx>
{
-> PatternKind<'tcx> {
let def = cx.tcx.def_map.borrow().get(&self.pat.id).unwrap().full_def();
match def {
def::DefVariant(enum_id, variant_id, _) => {
let adt_def = cx.tcx.lookup_adt_def(enum_id);
if adt_def.variants.len() > 1 {
PatternKind::Variant { adt_def: adt_def,
variant_index: adt_def.variant_index_with_id(variant_id),
subpatterns: subpatterns }
PatternKind::Variant {
adt_def: adt_def,
variant_index: adt_def.variant_index_with_id(variant_id),
subpatterns: subpatterns,
}
} else {
PatternKind::Leaf { subpatterns: subpatterns }
}
@ -130,9 +127,8 @@ impl<'tcx> PatNode<'tcx> {
}
_ => {
cx.tcx.sess.span_bug(
self.pat.span,
&format!("inappropriate def for pattern: {:?}", def));
cx.tcx.sess.span_bug(self.pat.span,
&format!("inappropriate def for pattern: {:?}", def));
}
}
}
@ -141,16 +137,15 @@ impl<'tcx> PatNode<'tcx> {
impl<'tcx> Mirror<'tcx> for PatNode<'tcx> {
type Output = Pattern<'tcx>;
fn make_mirror<'a>(self, cx: &mut Cx<'a,'tcx>) -> Pattern<'tcx> {
fn make_mirror<'a>(self, cx: &mut Cx<'a, 'tcx>) -> Pattern<'tcx> {
let kind = match self.pat.node {
hir::PatWild(..) =>
PatternKind::Wild,
hir::PatWild(..) => PatternKind::Wild,
hir::PatLit(ref value) => {
let value = const_eval::eval_const_expr(cx.tcx, value);
let value = Literal::Value { value: value };
PatternKind::Constant { value: value }
},
}
hir::PatRange(ref lo, ref hi) => {
let lo = const_eval::eval_const_expr(cx.tcx, lo);
@ -296,16 +291,16 @@ impl<'tcx> Mirror<'tcx> for PatNode<'tcx> {
}
hir::PatQPath(..) => {
cx.tcx.sess.span_bug(
self.pat.span,
"unexpanded macro or bad constant etc");
cx.tcx.sess.span_bug(self.pat.span, "unexpanded macro or bad constant etc");
}
};
let ty = cx.tcx.node_id_to_type(self.pat.id);
Pattern { span: self.pat.span,
ty: ty,
kind: kind }
Pattern {
span: self.pat.span,
ty: ty,
kind: kind,
}
}
}

View File

@ -86,7 +86,7 @@ impl<'a,'tcx:'a> ToRef for &'tcx hir::Field {
fn to_ref(self) -> FieldExprRef<'tcx> {
FieldExprRef {
name: Field::Named(self.name.node),
expr: self.expr.to_ref()
expr: self.expr.to_ref(),
}
}
}