//! [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/mir.html
use graphviz::IntoCow;
-use middle::region;
-use rustc_data_structures::sync::{Lrc};
-use rustc_data_structures::indexed_vec::{IndexVec, Idx};
-use rustc_data_structures::control_flow_graph::dominators::{Dominators, dominators};
-use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors};
-use rustc_data_structures::control_flow_graph::ControlFlowGraph;
-use rustc_data_structures::small_vec::SmallVec;
-use rustc_serialize as serialize;
use hir::def::CtorKind;
use hir::def_id::DefId;
-use mir::visit::MirVisitable;
-use mir::interpret::{Value, Scalar, EvalErrorKind};
-use ty::subst::{Subst, Substs};
-use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt};
-use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
-use util::ppaux;
-use std::slice;
use hir::{self, InlineAsm};
-use std::borrow::{Cow};
+use middle::region;
+use mir::interpret::{EvalErrorKind, Scalar, Value};
+use mir::visit::MirVisitable;
+use rustc_apfloat::ieee::{Double, Single};
+use rustc_apfloat::Float;
+use rustc_data_structures::control_flow_graph::dominators::{dominators, Dominators};
+use rustc_data_structures::control_flow_graph::ControlFlowGraph;
+use rustc_data_structures::control_flow_graph::{GraphPredecessors, GraphSuccessors};
+use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use rustc_data_structures::small_vec::SmallVec;
+use rustc_data_structures::sync::Lrc;
use rustc_data_structures::sync::ReadGuard;
+use rustc_serialize as serialize;
+use std::borrow::Cow;
use std::fmt::{self, Debug, Formatter, Write};
-use std::{iter, mem, option, u32};
use std::ops::{Index, IndexMut};
+use std::slice;
use std::vec::IntoIter;
+use std::{iter, mem, option, u32};
use syntax::ast::{self, Name};
use syntax::symbol::InternedString;
use syntax_pos::{Span, DUMMY_SP};
-use rustc_apfloat::ieee::{Single, Double};
-use rustc_apfloat::Float;
+use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
+use ty::subst::{Subst, Substs};
+use ty::{self, AdtDef, CanonicalTy, ClosureSubsts, GeneratorSubsts, Region, Ty, TyCtxt};
+use util::ppaux;
pub use mir::interpret::AssertMessage;
mod cache;
-pub mod tcx;
-pub mod visit;
-pub mod traversal;
pub mod interpret;
pub mod mono;
+pub mod tcx;
+pub mod traversal;
+pub mod visit;
/// Types for locals
type LocalDecls<'tcx> = IndexVec<Local, LocalDecl<'tcx>>;
pub span: Span,
/// A cache for various calculations
- cache: cache::Cache
+ cache: cache::Cache,
}
/// where execution begins
pub const START_BLOCK: BasicBlock = BasicBlock(0);
impl<'tcx> Mir<'tcx> {
- pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
- source_scopes: IndexVec<SourceScope, SourceScopeData>,
- source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope,
- SourceScopeLocalData>>,
- promoted: IndexVec<Promoted, Mir<'tcx>>,
- yield_ty: Option<Ty<'tcx>>,
- local_decls: IndexVec<Local, LocalDecl<'tcx>>,
- arg_count: usize,
- upvar_decls: Vec<UpvarDecl>,
- span: Span) -> Self
- {
+ pub fn new(
+ basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
+ source_scopes: IndexVec<SourceScope, SourceScopeData>,
+ source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
+ promoted: IndexVec<Promoted, Mir<'tcx>>,
+ yield_ty: Option<Ty<'tcx>>,
+ local_decls: IndexVec<Local, LocalDecl<'tcx>>,
+ arg_count: usize,
+ upvar_decls: Vec<UpvarDecl>,
+ span: Span,
+ ) -> Self {
// We need `arg_count` locals, and one for the return place
- assert!(local_decls.len() >= arg_count + 1,
- "expected at least {} locals, got {}", arg_count + 1, local_decls.len());
+ assert!(
+ local_decls.len() >= arg_count + 1,
+ "expected at least {} locals, got {}",
+ arg_count + 1,
+ local_decls.len()
+ );
Mir {
basic_blocks,
upvar_decls,
spread_arg: None,
span,
- cache: cache::Cache::new()
+ cache: cache::Cache::new(),
}
}
}
#[inline]
- pub fn basic_blocks_and_local_decls_mut(&mut self) -> (
+ pub fn basic_blocks_and_local_decls_mut(
+ &mut self,
+ ) -> (
&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>,
&mut LocalDecls<'tcx>,
) {
pub fn local_kind(&self, local: Local) -> LocalKind {
let index = local.0 as usize;
if index == 0 {
- debug_assert!(self.local_decls[local].mutability == Mutability::Mut,
- "return place should be mutable");
+ debug_assert!(
+ self.local_decls[local].mutability == Mutability::Mut,
+ "return place should be mutable"
+ );
LocalKind::ReturnPointer
} else if index < self.arg_count + 1 {
} else if self.local_decls[local].name.is_some() {
LocalKind::Var
} else {
- debug_assert!(self.local_decls[local].mutability == Mutability::Mut,
- "temp should be mutable");
+ debug_assert!(
+ self.local_decls[local].mutability == Mutability::Mut,
+ "temp should be mutable"
+ );
LocalKind::Temp
}
/// Returns an iterator over all temporaries.
#[inline]
- pub fn temps_iter<'a>(&'a self) -> impl Iterator<Item=Local> + 'a {
- (self.arg_count+1..self.local_decls.len()).filter_map(move |index| {
+ pub fn temps_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
+ (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
let local = Local::new(index);
if self.local_decls[local].is_user_variable.is_some() {
None
/// Returns an iterator over all user-declared locals.
#[inline]
- pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item=Local> + 'a {
- (self.arg_count+1..self.local_decls.len()).filter_map(move |index| {
+ pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
+ (self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
let local = Local::new(index);
if self.local_decls[local].is_user_variable.is_some() {
Some(local)
/// Returns an iterator over all user-declared mutable arguments and locals.
#[inline]
- pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item=Local> + 'a {
+ pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
(1..self.local_decls.len()).filter_map(move |index| {
let local = Local::new(index);
let decl = &self.local_decls[local];
if (decl.is_user_variable.is_some() || index < self.arg_count + 1)
- && decl.mutability == Mutability::Mut
+ && decl.mutability == Mutability::Mut
{
Some(local)
} else {
/// Returns an iterator over all function arguments.
#[inline]
- pub fn args_iter(&self) -> impl Iterator<Item=Local> {
+ pub fn args_iter(&self) -> impl Iterator<Item = Local> {
let arg_count = self.arg_count;
- (1..arg_count+1).map(Local::new)
+ (1..arg_count + 1).map(Local::new)
}
/// Returns an iterator over all user-defined variables and compiler-generated temporaries (all
/// locals that are neither arguments nor the return place).
#[inline]
- pub fn vars_and_temps_iter(&self) -> impl Iterator<Item=Local> {
+ pub fn vars_and_temps_iter(&self) -> impl Iterator<Item = Local> {
let arg_count = self.arg_count;
let local_count = self.local_decls.len();
- (arg_count+1..local_count).map(Local::new)
+ (arg_count + 1..local_count).map(Local::new)
}
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
/// Unsafe because of an unsafe fn
FnUnsafe,
/// Unsafe because of an `unsafe` block
- ExplicitUnsafe(ast::NodeId)
+ ExplicitUnsafe(ast::NodeId),
}
impl_stable_hash_for!(struct Mir<'tcx> {
#[derive(Copy, Clone, Debug)]
pub enum ClearCrossCrate<T> {
Clear,
- Set(T)
+ Set(T),
}
impl<T: serialize::Encodable> serialize::UseSpecializedEncodable for ClearCrossCrate<T> {}
/// The source scope, keeping track of which bindings can be
/// seen by debuginfo, active lint levels, `unsafe {...}`, etc.
- pub scope: SourceScope
+ pub scope: SourceScope,
}
///////////////////////////////////////////////////////////////////////////
}
}
-
#[derive(Copy, Clone, Debug, PartialEq, Eq, RustcEncodable, RustcDecodable)]
pub enum BorrowKind {
/// Data must be immutable and is aliasable.
Mut {
/// True if this borrow arose from method-call auto-ref
/// (i.e. `adjustment::Adjust::Borrow`)
- allow_two_phase_borrow: bool
- }
+ allow_two_phase_borrow: bool,
+ },
}
impl BorrowKind {
pub fn allows_two_phase_borrow(&self) -> bool {
match *self {
BorrowKind::Shared | BorrowKind::Unique => false,
- BorrowKind::Mut { allow_two_phase_borrow } => allow_two_phase_borrow,
+ BorrowKind::Mut {
+ allow_two_phase_borrow,
+ } => allow_two_phase_borrow,
}
}
}
/// - `fn foo(x: Type) { ... }`,
/// - `let x = ...`,
/// - or `match ... { C(x) => ... }`
- pub fn can_be_made_mutable(&self) -> bool
- {
+ pub fn can_be_made_mutable(&self) -> bool {
match self.is_user_variable {
Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
binding_mode: ty::BindingMode::BindByValue(_),
/// Returns true if local is definitely not a `ref ident` or
/// `ref mut ident` binding. (Such bindings cannot be made into
/// mutable bindings, but the inverse does not necessarily hold).
- pub fn is_nonref_binding(&self) -> bool
- {
+ pub fn is_nonref_binding(&self) -> bool {
match self.is_user_variable {
Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm {
binding_mode: ty::BindingMode::BindByValue(_),
name: None,
source_info: SourceInfo {
span,
- scope: OUTERMOST_SOURCE_SCOPE
+ scope: OUTERMOST_SOURCE_SCOPE,
},
visibility_scope: OUTERMOST_SOURCE_SCOPE,
internal: false,
name: None,
source_info: SourceInfo {
span,
- scope: OUTERMOST_SOURCE_SCOPE
+ scope: OUTERMOST_SOURCE_SCOPE,
},
visibility_scope: OUTERMOST_SOURCE_SCOPE,
internal: true,
ty: return_ty,
source_info: SourceInfo {
span,
- scope: OUTERMOST_SOURCE_SCOPE
+ scope: OUTERMOST_SOURCE_SCOPE,
},
visibility_scope: OUTERMOST_SOURCE_SCOPE,
internal: false,
- name: None, // FIXME maybe we do want some name here?
+ name: None, // FIXME maybe we do want some name here?
is_user_variable: None,
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub struct Terminator<'tcx> {
pub source_info: SourceInfo,
- pub kind: TerminatorKind<'tcx>
+ pub kind: TerminatorKind<'tcx>,
}
#[derive(Clone, RustcEncodable, RustcDecodable)]
pub enum TerminatorKind<'tcx> {
/// block should have one successor in the graph; we jump there
- Goto {
- target: BasicBlock,
- },
+ Goto { target: BasicBlock },
/// operand evaluates to an integer; jump depending on its value
/// to one of the targets, and otherwise fallback to `otherwise`
Drop {
location: Place<'tcx>,
target: BasicBlock,
- unwind: Option<BasicBlock>
+ unwind: Option<BasicBlock>,
},
/// Drop the Place and assign the new value over it. This ensures
/// Destination for the return value. If some, the call is converging.
destination: Option<(Place<'tcx>, BasicBlock)>,
/// Cleanups to be done if the call unwinds.
- cleanup: Option<BasicBlock>
+ cleanup: Option<BasicBlock>,
},
/// Jump to the target if the condition has the expected value,
expected: bool,
msg: AssertMessage<'tcx>,
target: BasicBlock,
- cleanup: Option<BasicBlock>
+ cleanup: Option<BasicBlock>,
},
/// A suspend point
}
impl<'tcx> TerminatorKind<'tcx> {
- pub fn if_<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, cond: Operand<'tcx>,
- t: BasicBlock, f: BasicBlock) -> TerminatorKind<'tcx> {
+ pub fn if_<'a, 'gcx>(
+ tcx: TyCtxt<'a, 'gcx, 'tcx>,
+ cond: Operand<'tcx>,
+ t: BasicBlock,
+ f: BasicBlock,
+ ) -> TerminatorKind<'tcx> {
static BOOL_SWITCH_FALSE: &'static [u128] = &[0];
TerminatorKind::SwitchInt {
discr: cond,
pub fn successors(&self) -> Successors {
use self::TerminatorKind::*;
match *self {
- Resume | Abort | GeneratorDrop | Return | Unreachable |
- Call { destination: None, cleanup: None, .. } => {
- None.into_iter().chain(&[])
+ Resume
+ | Abort
+ | GeneratorDrop
+ | Return
+ | Unreachable
+ | Call {
+ destination: None,
+ cleanup: None,
+ ..
+ } => None.into_iter().chain(&[]),
+ Goto { target: ref t }
+ | Call {
+ destination: None,
+ cleanup: Some(ref t),
+ ..
+ }
+ | Call {
+ destination: Some((_, ref t)),
+ cleanup: None,
+ ..
+ }
+ | Yield {
+ resume: ref t,
+ drop: None,
+ ..
+ }
+ | DropAndReplace {
+ target: ref t,
+ unwind: None,
+ ..
+ }
+ | Drop {
+ target: ref t,
+ unwind: None,
+ ..
+ }
+ | Assert {
+ target: ref t,
+ cleanup: None,
+ ..
+ }
+ | FalseUnwind {
+ real_target: ref t,
+ unwind: None,
+ } => Some(t).into_iter().chain(&[]),
+ Call {
+ destination: Some((_, ref t)),
+ cleanup: Some(ref u),
+ ..
}
- Goto { target: ref t } |
- Call { destination: None, cleanup: Some(ref t), .. } |
- Call { destination: Some((_, ref t)), cleanup: None, .. } |
- Yield { resume: ref t, drop: None, .. } |
- DropAndReplace { target: ref t, unwind: None, .. } |
- Drop { target: ref t, unwind: None, .. } |
- Assert { target: ref t, cleanup: None, .. } |
- FalseUnwind { real_target: ref t, unwind: None } => {
- Some(t).into_iter().chain(&[])
+ | Yield {
+ resume: ref t,
+ drop: Some(ref u),
+ ..
}
- Call { destination: Some((_, ref t)), cleanup: Some(ref u), .. } |
- Yield { resume: ref t, drop: Some(ref u), .. } |
- DropAndReplace { target: ref t, unwind: Some(ref u), .. } |
- Drop { target: ref t, unwind: Some(ref u), .. } |
- Assert { target: ref t, cleanup: Some(ref u), .. } |
- FalseUnwind { real_target: ref t, unwind: Some(ref u) } => {
- Some(t).into_iter().chain(slice::from_ref(u))
+ | DropAndReplace {
+ target: ref t,
+ unwind: Some(ref u),
+ ..
}
- SwitchInt { ref targets, .. } => {
- None.into_iter().chain(&targets[..])
+ | Drop {
+ target: ref t,
+ unwind: Some(ref u),
+ ..
}
- FalseEdges { ref real_target, ref imaginary_targets } => {
- Some(real_target).into_iter().chain(&imaginary_targets[..])
+ | Assert {
+ target: ref t,
+ cleanup: Some(ref u),
+ ..
}
+ | FalseUnwind {
+ real_target: ref t,
+ unwind: Some(ref u),
+ } => Some(t).into_iter().chain(slice::from_ref(u)),
+ SwitchInt { ref targets, .. } => None.into_iter().chain(&targets[..]),
+ FalseEdges {
+ ref real_target,
+ ref imaginary_targets,
+ } => Some(real_target).into_iter().chain(&imaginary_targets[..]),
}
}
pub fn successors_mut(&mut self) -> SuccessorsMut {
use self::TerminatorKind::*;
match *self {
- Resume | Abort | GeneratorDrop | Return | Unreachable |
- Call { destination: None, cleanup: None, .. } => {
- None.into_iter().chain(&mut [])
+ Resume
+ | Abort
+ | GeneratorDrop
+ | Return
+ | Unreachable
+ | Call {
+ destination: None,
+ cleanup: None,
+ ..
+ } => None.into_iter().chain(&mut []),
+ Goto { target: ref mut t }
+ | Call {
+ destination: None,
+ cleanup: Some(ref mut t),
+ ..
}
- Goto { target: ref mut t } |
- Call { destination: None, cleanup: Some(ref mut t), .. } |
- Call { destination: Some((_, ref mut t)), cleanup: None, .. } |
- Yield { resume: ref mut t, drop: None, .. } |
- DropAndReplace { target: ref mut t, unwind: None, .. } |
- Drop { target: ref mut t, unwind: None, .. } |
- Assert { target: ref mut t, cleanup: None, .. } |
- FalseUnwind { real_target: ref mut t, unwind: None } => {
- Some(t).into_iter().chain(&mut [])
+ | Call {
+ destination: Some((_, ref mut t)),
+ cleanup: None,
+ ..
}
- Call { destination: Some((_, ref mut t)), cleanup: Some(ref mut u), .. } |
- Yield { resume: ref mut t, drop: Some(ref mut u), .. } |
- DropAndReplace { target: ref mut t, unwind: Some(ref mut u), .. } |
- Drop { target: ref mut t, unwind: Some(ref mut u), .. } |
- Assert { target: ref mut t, cleanup: Some(ref mut u), .. } |
- FalseUnwind { real_target: ref mut t, unwind: Some(ref mut u) } => {
- Some(t).into_iter().chain(slice::from_mut(u))
+ | Yield {
+ resume: ref mut t,
+ drop: None,
+ ..
}
- SwitchInt { ref mut targets, .. } => {
- None.into_iter().chain(&mut targets[..])
+ | DropAndReplace {
+ target: ref mut t,
+ unwind: None,
+ ..
}
- FalseEdges { ref mut real_target, ref mut imaginary_targets } => {
- Some(real_target).into_iter().chain(&mut imaginary_targets[..])
+ | Drop {
+ target: ref mut t,
+ unwind: None,
+ ..
}
+ | Assert {
+ target: ref mut t,
+ cleanup: None,
+ ..
+ }
+ | FalseUnwind {
+ real_target: ref mut t,
+ unwind: None,
+ } => Some(t).into_iter().chain(&mut []),
+ Call {
+ destination: Some((_, ref mut t)),
+ cleanup: Some(ref mut u),
+ ..
+ }
+ | Yield {
+ resume: ref mut t,
+ drop: Some(ref mut u),
+ ..
+ }
+ | DropAndReplace {
+ target: ref mut t,
+ unwind: Some(ref mut u),
+ ..
+ }
+ | Drop {
+ target: ref mut t,
+ unwind: Some(ref mut u),
+ ..
+ }
+ | Assert {
+ target: ref mut t,
+ cleanup: Some(ref mut u),
+ ..
+ }
+ | FalseUnwind {
+ real_target: ref mut t,
+ unwind: Some(ref mut u),
+ } => Some(t).into_iter().chain(slice::from_mut(u)),
+ SwitchInt {
+ ref mut targets, ..
+ } => None.into_iter().chain(&mut targets[..]),
+ FalseEdges {
+ ref mut real_target,
+ ref mut imaginary_targets,
+ } => Some(real_target)
+ .into_iter()
+ .chain(&mut imaginary_targets[..]),
}
}
pub fn unwind_mut(&mut self) -> Option<&mut Option<BasicBlock>> {
match *self {
- TerminatorKind::Goto { .. } |
- TerminatorKind::Resume |
- TerminatorKind::Abort |
- TerminatorKind::Return |
- TerminatorKind::Unreachable |
- TerminatorKind::GeneratorDrop |
- TerminatorKind::Yield { .. } |
- TerminatorKind::SwitchInt { .. } |
- TerminatorKind::FalseEdges { .. } => {
- None
- },
- TerminatorKind::Call { cleanup: ref mut unwind, .. } |
- TerminatorKind::Assert { cleanup: ref mut unwind, .. } |
- TerminatorKind::DropAndReplace { ref mut unwind, .. } |
- TerminatorKind::Drop { ref mut unwind, .. } |
- TerminatorKind::FalseUnwind { ref mut unwind, .. } => {
- Some(unwind)
+ TerminatorKind::Goto { .. }
+ | TerminatorKind::Resume
+ | TerminatorKind::Abort
+ | TerminatorKind::Return
+ | TerminatorKind::Unreachable
+ | TerminatorKind::GeneratorDrop
+ | TerminatorKind::Yield { .. }
+ | TerminatorKind::SwitchInt { .. }
+ | TerminatorKind::FalseEdges { .. } => None,
+ TerminatorKind::Call {
+ cleanup: ref mut unwind,
+ ..
}
+ | TerminatorKind::Assert {
+ cleanup: ref mut unwind,
+ ..
+ }
+ | TerminatorKind::DropAndReplace { ref mut unwind, .. }
+ | TerminatorKind::Drop { ref mut unwind, .. }
+ | TerminatorKind::FalseUnwind { ref mut unwind, .. } => Some(unwind),
}
}
}
self.terminator.as_mut().expect("invalid terminator state")
}
- pub fn retain_statements<F>(&mut self, mut f: F) where F: FnMut(&mut Statement) -> bool {
+ pub fn retain_statements<F>(&mut self, mut f: F)
+ where
+ F: FnMut(&mut Statement) -> bool,
+ {
for s in &mut self.statements {
if !f(s) {
s.make_nop();
}
pub fn expand_statements<F, I>(&mut self, mut f: F)
- where F: FnMut(&mut Statement<'tcx>) -> Option<I>,
- I: iter::TrustedLen<Item = Statement<'tcx>>
+ where
+ F: FnMut(&mut Statement<'tcx>) -> Option<I>,
+ I: iter::TrustedLen<Item = Statement<'tcx>>,
{
// Gather all the iterators we'll need to splice in, and their positions.
let mut splices: Vec<(usize, I)> = vec![];
// splicing adding new elements to the end of that gap and moving
// existing elements from before the gap to the end of the gap.
// For now, this is safe code, emulating a gap but initializing it.
- let mut gap = self.statements.len()..self.statements.len()+extra_stmts;
- self.statements.resize(gap.end, Statement {
- source_info: SourceInfo {
- span: DUMMY_SP,
- scope: OUTERMOST_SOURCE_SCOPE
+ let mut gap = self.statements.len()..self.statements.len() + extra_stmts;
+ self.statements.resize(
+ gap.end,
+ Statement {
+ source_info: SourceInfo {
+ span: DUMMY_SP,
+ scope: OUTERMOST_SOURCE_SCOPE,
+ },
+ kind: StatementKind::Nop,
},
- kind: StatementKind::Nop
- });
+ );
for (splice_start, new_stmts) in splices.into_iter().rev() {
let splice_end = splice_start + new_stmts.size_hint().0;
while gap.end > splice_end {
}
write!(fmt, "]")
}
-
}
}
}
use self::TerminatorKind::*;
match *self {
Goto { .. } => write!(fmt, "goto"),
- SwitchInt { discr: ref place, .. } => write!(fmt, "switchInt({:?})", place),
+ SwitchInt {
+ discr: ref place, ..
+ } => write!(fmt, "switchInt({:?})", place),
Return => write!(fmt, "return"),
GeneratorDrop => write!(fmt, "generator_drop"),
Resume => write!(fmt, "resume"),
Yield { ref value, .. } => write!(fmt, "_1 = suspend({:?})", value),
Unreachable => write!(fmt, "unreachable"),
Drop { ref location, .. } => write!(fmt, "drop({:?})", location),
- DropAndReplace { ref location, ref value, .. } =>
- write!(fmt, "replace({:?} <- {:?})", location, value),
- Call { ref func, ref args, ref destination, .. } => {
+ DropAndReplace {
+ ref location,
+ ref value,
+ ..
+ } => write!(fmt, "replace({:?} <- {:?})", location, value),
+ Call {
+ ref func,
+ ref args,
+ ref destination,
+ ..
+ } => {
if let Some((ref destination, _)) = *destination {
write!(fmt, "{:?} = ", destination)?;
}
}
write!(fmt, ")")
}
- Assert { ref cond, expected, ref msg, .. } => {
+ Assert {
+ ref cond,
+ expected,
+ ref msg,
+ ..
+ } => {
write!(fmt, "assert(")?;
if !expected {
write!(fmt, "!")?;
}
write!(fmt, "{:?}, \"{:?}\")", cond, msg)
- },
+ }
FalseEdges { .. } => write!(fmt, "falseEdges"),
FalseUnwind { .. } => write!(fmt, "falseUnwind"),
}
match *self {
Return | Resume | Abort | Unreachable | GeneratorDrop => vec![],
Goto { .. } => vec!["".into()],
- SwitchInt { ref values, switch_ty, .. } => {
+ SwitchInt {
+ ref values,
+ switch_ty,
+ ..
+ } => {
let size = ty::tls::with(|tcx| {
let param_env = ty::ParamEnv::empty();
let switch_ty = tcx.lift_to_global(&switch_ty).unwrap();
tcx.layout_of(param_env.and(switch_ty)).unwrap().size
});
- values.iter()
- .map(|&u| {
- let mut s = String::new();
- print_miri_value(
- Value::Scalar(Scalar::Bits { bits: u, defined: size.bits() as u8 }),
- switch_ty,
- &mut s,
- ).unwrap();
- s.into()
- })
- .chain(iter::once(String::from("otherwise").into()))
- .collect()
+ values
+ .iter()
+ .map(|&u| {
+ let mut s = String::new();
+ print_miri_value(
+ Value::Scalar(Scalar::Bits {
+ bits: u,
+ defined: size.bits() as u8,
+ }),
+ switch_ty,
+ &mut s,
+ ).unwrap();
+ s.into()
+ })
+ .chain(iter::once(String::from("otherwise").into()))
+ .collect()
}
- Call { destination: Some(_), cleanup: Some(_), .. } =>
- vec!["return".into_cow(), "unwind".into_cow()],
- Call { destination: Some(_), cleanup: None, .. } => vec!["return".into_cow()],
- Call { destination: None, cleanup: Some(_), .. } => vec!["unwind".into_cow()],
- Call { destination: None, cleanup: None, .. } => vec![],
- Yield { drop: Some(_), .. } =>
- vec!["resume".into_cow(), "drop".into_cow()],
+ Call {
+ destination: Some(_),
+ cleanup: Some(_),
+ ..
+ } => vec!["return".into_cow(), "unwind".into_cow()],
+ Call {
+ destination: Some(_),
+ cleanup: None,
+ ..
+ } => vec!["return".into_cow()],
+ Call {
+ destination: None,
+ cleanup: Some(_),
+ ..
+ } => vec!["unwind".into_cow()],
+ Call {
+ destination: None,
+ cleanup: None,
+ ..
+ } => vec![],
+ Yield { drop: Some(_), .. } => vec!["resume".into_cow(), "drop".into_cow()],
Yield { drop: None, .. } => vec!["resume".into_cow()],
- DropAndReplace { unwind: None, .. } |
- Drop { unwind: None, .. } => vec!["return".into_cow()],
- DropAndReplace { unwind: Some(_), .. } |
- Drop { unwind: Some(_), .. } => {
- vec!["return".into_cow(), "unwind".into_cow()]
+ DropAndReplace { unwind: None, .. } | Drop { unwind: None, .. } => {
+ vec!["return".into_cow()]
+ }
+ DropAndReplace {
+ unwind: Some(_), ..
}
+ | Drop {
+ unwind: Some(_), ..
+ } => vec!["return".into_cow(), "unwind".into_cow()],
Assert { cleanup: None, .. } => vec!["".into()],
- Assert { .. } =>
- vec!["success".into_cow(), "unwind".into_cow()],
- FalseEdges { ref imaginary_targets, .. } => {
+ Assert { .. } => vec!["success".into_cow(), "unwind".into_cow()],
+ FalseEdges {
+ ref imaginary_targets,
+ ..
+ } => {
let mut l = vec!["real".into()];
l.resize(imaginary_targets.len() + 1, "imaginary".into());
l
}
- FalseUnwind { unwind: Some(_), .. } => vec!["real".into(), "cleanup".into()],
+ FalseUnwind {
+ unwind: Some(_), ..
+ } => vec!["real".into(), "cleanup".into()],
FalseUnwind { unwind: None, .. } => vec!["real".into()],
}
}
pub fn replace_nop(&mut self) -> Self {
Statement {
source_info: self.source_info,
- kind: mem::replace(&mut self.kind, StatementKind::Nop)
+ kind: mem::replace(&mut self.kind, StatementKind::Nop),
}
}
}
ReadForMatch(Place<'tcx>),
/// Write the discriminant for a variant to the enum Place.
- SetDiscriminant { place: Place<'tcx>, variant_index: usize },
+ SetDiscriminant {
+ place: Place<'tcx>,
+ variant_index: usize,
+ },
/// Start a live range for the storage of the local.
StorageLive(Local),
InlineAsm {
asm: Box<InlineAsm>,
outputs: Vec<Place<'tcx>>,
- inputs: Vec<Operand<'tcx>>
+ inputs: Vec<Operand<'tcx>>,
},
/// Assert the given places to be valid inhabitants of their type. These statements are
Validate(ref op, ref places) => write!(fmt, "Validate({:?}, {:?})", op, places),
StorageLive(ref place) => write!(fmt, "StorageLive({:?})", place),
StorageDead(ref place) => write!(fmt, "StorageDead({:?})", place),
- SetDiscriminant { ref place, variant_index } => {
- write!(fmt, "discriminant({:?}) = {:?}", place, variant_index)
- },
- InlineAsm { ref asm, ref outputs, ref inputs } => {
- write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs)
- },
- UserAssertTy(ref c_ty, ref local) => write!(fmt, "UserAssertTy({:?}, {:?})",
- c_ty, local),
+ SetDiscriminant {
+ ref place,
+ variant_index,
+ } => write!(fmt, "discriminant({:?}) = {:?}", place, variant_index),
+ InlineAsm {
+ ref asm,
+ ref outputs,
+ ref inputs,
+ } => write!(fmt, "asm!({:?} : {:?} : {:?})", asm, outputs, inputs),
+ UserAssertTy(ref c_ty, ref local) => {
+ write!(fmt, "UserAssertTy({:?}, {:?})", c_ty, local)
+ }
Nop => write!(fmt, "nop"),
}
}
}
pub fn elem(self, elem: PlaceElem<'tcx>) -> Place<'tcx> {
- Place::Projection(Box::new(PlaceProjection {
- base: self,
- elem,
- }))
+ Place::Projection(Box::new(PlaceProjection { base: self, elem }))
}
}
match *self {
Local(id) => write!(fmt, "{:?}", id),
- Static(box self::Static { def_id, ty }) =>
- write!(fmt, "({}: {:?})", ty::tls::with(|tcx| tcx.item_path_str(def_id)), ty),
- Projection(ref data) =>
- match data.elem {
- ProjectionElem::Downcast(ref adt_def, index) =>
- write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].name),
- ProjectionElem::Deref =>
- write!(fmt, "(*{:?})", data.base),
- ProjectionElem::Field(field, ty) =>
- write!(fmt, "({:?}.{:?}: {:?})", data.base, field.index(), ty),
- ProjectionElem::Index(ref index) =>
- write!(fmt, "{:?}[{:?}]", data.base, index),
- ProjectionElem::ConstantIndex { offset, min_length, from_end: false } =>
- write!(fmt, "{:?}[{:?} of {:?}]", data.base, offset, min_length),
- ProjectionElem::ConstantIndex { offset, min_length, from_end: true } =>
- write!(fmt, "{:?}[-{:?} of {:?}]", data.base, offset, min_length),
- ProjectionElem::Subslice { from, to } if to == 0 =>
- write!(fmt, "{:?}[{:?}:]", data.base, from),
- ProjectionElem::Subslice { from, to } if from == 0 =>
- write!(fmt, "{:?}[:-{:?}]", data.base, to),
- ProjectionElem::Subslice { from, to } =>
- write!(fmt, "{:?}[{:?}:-{:?}]", data.base,
- from, to),
-
- },
+ Static(box self::Static { def_id, ty }) => write!(
+ fmt,
+ "({}: {:?})",
+ ty::tls::with(|tcx| tcx.item_path_str(def_id)),
+ ty
+ ),
+ Projection(ref data) => match data.elem {
+ ProjectionElem::Downcast(ref adt_def, index) => {
+ write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].name)
+ }
+ ProjectionElem::Deref => write!(fmt, "(*{:?})", data.base),
+ ProjectionElem::Field(field, ty) => {
+ write!(fmt, "({:?}.{:?}: {:?})", data.base, field.index(), ty)
+ }
+ ProjectionElem::Index(ref index) => write!(fmt, "{:?}[{:?}]", data.base, index),
+ ProjectionElem::ConstantIndex {
+ offset,
+ min_length,
+ from_end: false,
+ } => write!(fmt, "{:?}[{:?} of {:?}]", data.base, offset, min_length),
+ ProjectionElem::ConstantIndex {
+ offset,
+ min_length,
+ from_end: true,
+ } => write!(fmt, "{:?}[-{:?} of {:?}]", data.base, offset, min_length),
+ ProjectionElem::Subslice { from, to } if to == 0 => {
+ write!(fmt, "{:?}[{:?}:]", data.base, from)
+ }
+ ProjectionElem::Subslice { from, to } if from == 0 => {
+ write!(fmt, "{:?}[:-{:?}]", data.base, to)
+ }
+ ProjectionElem::Subslice { from, to } => {
+ write!(fmt, "{:?}[{:?}:-{:?}]", data.base, from, to)
+ }
+ },
}
}
}
pub fn to_copy(&self) -> Self {
match *self {
Operand::Copy(_) | Operand::Constant(_) => self.clone(),
- Operand::Move(ref place) => Operand::Copy(place.clone())
+ Operand::Move(ref place) => Operand::Copy(place.clone()),
}
}
}
use self::BinOp::*;
match self {
Add | Sub | Mul | Shl | Shr => true,
- _ => false
+ _ => false,
}
}
}
// When printing regions, add trailing space if necessary.
let region = if ppaux::verbose() || ppaux::identify_regions() {
let mut region = format!("{}", region);
- if region.len() > 0 { region.push(' '); }
+ if region.len() > 0 {
+ region.push(' ');
+ }
region
} else {
// Do not even print 'static
match **kind {
AggregateKind::Array(_) => write!(fmt, "{:?}", places),
- AggregateKind::Tuple => {
- match places.len() {
- 0 => write!(fmt, "()"),
- 1 => write!(fmt, "({:?},)", places[0]),
- _ => fmt_tuple(fmt, places),
- }
- }
+ AggregateKind::Tuple => match places.len() {
+ 0 => write!(fmt, "()"),
+ 1 => write!(fmt, "({:?},)", places[0]),
+ _ => fmt_tuple(fmt, places),
+ },
AggregateKind::Adt(adt_def, variant, substs, _) => {
let variant_def = &adt_def.variants[variant];
}
struct_fmt.field("$state", &places[freevars.len()]);
for i in (freevars.len() + 1)..places.len() {
- struct_fmt.field(&format!("${}", i - freevars.len() - 1),
- &places[i]);
+ struct_fmt
+ .field(&format!("${}", i - freevars.len() - 1), &places[i]);
}
});
newtype_index!(Promoted { DEBUG_FORMAT = "promoted[{}]" });
-
#[derive(Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum Literal<'tcx> {
Value {
},
Promoted {
// Index into the `promoted` vector of `Mir`.
- index: Promoted
+ index: Promoted,
},
}
write!(fmt, "const ")?;
fmt_const_val(fmt, value)
}
- Promoted { index } => {
- write!(fmt, "{:?}", index)
- }
+ Promoted { index } => write!(fmt, "{:?}", index),
}
}
}
} else {
write!(fmt, "{:?}:{}", val, const_val.ty)
}
- },
+ }
}
}
match (value, &ty.sty) {
(Value::Scalar(Scalar::Bits { bits: 0, .. }), &TyBool) => write!(f, "false"),
(Value::Scalar(Scalar::Bits { bits: 1, .. }), &TyBool) => write!(f, "true"),
- (Value::Scalar(Scalar::Bits { bits, .. }), &TyFloat(ast::FloatTy::F32)) =>
- write!(f, "{}f32", Single::from_bits(bits)),
- (Value::Scalar(Scalar::Bits { bits, .. }), &TyFloat(ast::FloatTy::F64)) =>
- write!(f, "{}f64", Double::from_bits(bits)),
+ (Value::Scalar(Scalar::Bits { bits, .. }), &TyFloat(ast::FloatTy::F32)) => {
+ write!(f, "{}f32", Single::from_bits(bits))
+ }
+ (Value::Scalar(Scalar::Bits { bits, .. }), &TyFloat(ast::FloatTy::F64)) => {
+ write!(f, "{}f64", Double::from_bits(bits))
+ }
(Value::Scalar(Scalar::Bits { bits, .. }), &TyUint(ui)) => write!(f, "{:?}{}", bits, ui),
(Value::Scalar(Scalar::Bits { bits, .. }), &TyInt(i)) => {
let bit_width = ty::tls::with(|tcx| {
- let ty = tcx.lift_to_global(&ty).unwrap();
- tcx.layout_of(ty::ParamEnv::empty().and(ty)).unwrap().size.bits()
+ let ty = tcx.lift_to_global(&ty).unwrap();
+ tcx.layout_of(ty::ParamEnv::empty().and(ty))
+ .unwrap()
+ .size
+ .bits()
});
let shift = 128 - bit_width;
write!(f, "{:?}{}", ((bits as i128) << shift) >> shift, i)
- },
- (Value::Scalar(Scalar::Bits { bits, .. }), &TyChar) =>
- write!(f, "{:?}", ::std::char::from_u32(bits as u32).unwrap()),
- (_, &TyFnDef(did, _)) =>
- write!(f, "{}", item_path_str(did)),
- (Value::ScalarPair(Scalar::Ptr(ptr), Scalar::Bits { bits: len, .. }),
- &TyRef(_, &ty::TyS { sty: TyStr, .. }, _)) => {
- ty::tls::with(|tcx| {
- match tcx.alloc_map.lock().get(ptr.alloc_id) {
- Some(interpret::AllocType::Memory(alloc)) => {
- assert_eq!(len as usize as u128, len);
- let slice = &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
- let s = ::std::str::from_utf8(slice)
- .expect("non utf8 str from miri");
- write!(f, "{:?}", s)
- }
- _ => write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len),
- }
- })
- },
+ }
+ (Value::Scalar(Scalar::Bits { bits, .. }), &TyChar) => {
+ write!(f, "{:?}", ::std::char::from_u32(bits as u32).unwrap())
+ }
+ (_, &TyFnDef(did, _)) => write!(f, "{}", item_path_str(did)),
+ (
+ Value::ScalarPair(Scalar::Ptr(ptr), Scalar::Bits { bits: len, .. }),
+ &TyRef(_, &ty::TyS { sty: TyStr, .. }, _),
+ ) => ty::tls::with(|tcx| match tcx.alloc_map.lock().get(ptr.alloc_id) {
+ Some(interpret::AllocType::Memory(alloc)) => {
+ assert_eq!(len as usize as u128, len);
+ let slice = &alloc.bytes[(ptr.offset.bytes() as usize)..][..(len as usize)];
+ let s = ::std::str::from_utf8(slice).expect("non utf8 str from miri");
+ write!(f, "{:?}", s)
+ }
+ _ => write!(f, "pointer to erroneous constant {:?}, {:?}", ptr, len),
+ }),
_ => write!(f, "{:?}:{}", value, ty),
}
}
}
impl<'tcx> ControlFlowGraph for Mir<'tcx> {
-
type Node = BasicBlock;
- fn num_nodes(&self) -> usize { self.basic_blocks.len() }
+ fn num_nodes(&self) -> usize {
+ self.basic_blocks.len()
+ }
- fn start_node(&self) -> Self::Node { START_BLOCK }
+ fn start_node(&self) -> Self::Node {
+ START_BLOCK
+ }
- fn predecessors<'graph>(&'graph self, node: Self::Node)
- -> <Self as GraphPredecessors<'graph>>::Iter
- {
+ fn predecessors<'graph>(
+ &'graph self,
+ node: Self::Node,
+ ) -> <Self as GraphPredecessors<'graph>>::Iter {
self.predecessors_for(node).clone().into_iter()
}
- fn successors<'graph>(&'graph self, node: Self::Node)
- -> <Self as GraphSuccessors<'graph>>::Iter
- {
+ fn successors<'graph>(
+ &'graph self,
+ node: Self::Node,
+ ) -> <Self as GraphSuccessors<'graph>>::Iter {
self.basic_blocks[node].terminator().successors().cloned()
}
}
type Iter = IntoIter<BasicBlock>;
}
-impl<'a, 'b> GraphSuccessors<'b> for Mir<'a> {
+impl<'a, 'b> GraphSuccessors<'b> for Mir<'a> {
type Item = BasicBlock;
type Iter = iter::Cloned<Successors<'b>>;
}
/// Note that if this location represents a terminator, then the
/// resulting location would be out of bounds and invalid.
pub fn successor_within_block(&self) -> Location {
- Location { block: self.block, statement_index: self.statement_index + 1 }
+ Location {
+ block: self.block,
+ statement_index: self.statement_index + 1,
+ }
}
pub fn dominates(&self, other: Location, dominators: &Dominators<BasicBlock>) -> bool {
let kind = match self.kind {
Goto { target } => Goto { target: target },
- SwitchInt { ref discr, switch_ty, ref values, ref targets } => SwitchInt {
+ SwitchInt {
+ ref discr,
+ switch_ty,
+ ref values,
+ ref targets,
+ } => SwitchInt {
discr: discr.fold_with(folder),
switch_ty: switch_ty.fold_with(folder),
values: values.clone(),
- targets: targets.clone()
+ targets: targets.clone(),
},
- Drop { ref location, target, unwind } => Drop {
+ Drop {
+ ref location,
+ target,
+ unwind,
+ } => Drop {
location: location.fold_with(folder),
target,
unwind,
},
- DropAndReplace { ref location, ref value, target, unwind } => DropAndReplace {
+ DropAndReplace {
+ ref location,
+ ref value,
+ target,
+ unwind,
+ } => DropAndReplace {
location: location.fold_with(folder),
value: value.fold_with(folder),
target,
unwind,
},
- Yield { ref value, resume, drop } => Yield {
+ Yield {
+ ref value,
+ resume,
+ drop,
+ } => Yield {
value: value.fold_with(folder),
resume: resume,
drop: drop,
},
- Call { ref func, ref args, ref destination, cleanup } => {
- let dest = destination.as_ref().map(|&(ref loc, dest)| {
- (loc.fold_with(folder), dest)
- });
+ Call {
+ ref func,
+ ref args,
+ ref destination,
+ cleanup,
+ } => {
+ let dest = destination
+ .as_ref()
+ .map(|&(ref loc, dest)| (loc.fold_with(folder), dest));
Call {
func: func.fold_with(folder),
destination: dest,
cleanup,
}
- },
- Assert { ref cond, expected, ref msg, target, cleanup } => {
+ }
+ Assert {
+ ref cond,
+ expected,
+ ref msg,
+ target,
+ cleanup,
+ } => {
let msg = if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
EvalErrorKind::BoundsCheck {
len: len.fold_with(folder),
target,
cleanup,
}
- },
+ }
GeneratorDrop => GeneratorDrop,
Resume => Resume,
Abort => Abort,
Return => Return,
Unreachable => Unreachable,
- FalseEdges { real_target, ref imaginary_targets } =>
- FalseEdges { real_target, imaginary_targets: imaginary_targets.clone() },
- FalseUnwind { real_target, unwind } => FalseUnwind { real_target, unwind },
+ FalseEdges {
+ real_target,
+ ref imaginary_targets,
+ } => FalseEdges {
+ real_target,
+ imaginary_targets: imaginary_targets.clone(),
+ },
+ FalseUnwind {
+ real_target,
+ unwind,
+ } => FalseUnwind {
+ real_target,
+ unwind,
+ },
};
Terminator {
source_info: self.source_info,
use mir::TerminatorKind::*;
match self.kind {
- SwitchInt { ref discr, switch_ty, .. } =>
- discr.visit_with(visitor) || switch_ty.visit_with(visitor),
- Drop { ref location, ..} => location.visit_with(visitor),
- DropAndReplace { ref location, ref value, ..} =>
- location.visit_with(visitor) || value.visit_with(visitor),
- Yield { ref value, ..} =>
- value.visit_with(visitor),
- Call { ref func, ref args, ref destination, .. } => {
+ SwitchInt {
+ ref discr,
+ switch_ty,
+ ..
+ } => discr.visit_with(visitor) || switch_ty.visit_with(visitor),
+ Drop { ref location, .. } => location.visit_with(visitor),
+ DropAndReplace {
+ ref location,
+ ref value,
+ ..
+ } => location.visit_with(visitor) || value.visit_with(visitor),
+ Yield { ref value, .. } => value.visit_with(visitor),
+ Call {
+ ref func,
+ ref args,
+ ref destination,
+ ..
+ } => {
let dest = if let Some((ref loc, _)) = *destination {
loc.visit_with(visitor)
- } else { false };
+ } else {
+ false
+ };
dest || func.visit_with(visitor) || args.visit_with(visitor)
- },
- Assert { ref cond, ref msg, .. } => {
+ }
+ Assert {
+ ref cond, ref msg, ..
+ } => {
if cond.visit_with(visitor) {
if let EvalErrorKind::BoundsCheck { ref len, ref index } = *msg {
len.visit_with(visitor) || index.visit_with(visitor)
} else {
false
}
- },
- Goto { .. } |
- Resume |
- Abort |
- Return |
- GeneratorDrop |
- Unreachable |
- FalseEdges { .. } |
- FalseUnwind { .. } => false
+ }
+ Goto { .. }
+ | Resume
+ | Abort
+ | Return
+ | GeneratorDrop
+ | Unreachable
+ | FalseEdges { .. }
+ | FalseUnwind { .. } => false,
}
}
}
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
match self {
&Place::Projection(ref p) => Place::Projection(p.fold_with(folder)),
- _ => self.clone()
+ _ => self.clone(),
}
}
match *self {
Use(ref op) => Use(op.fold_with(folder)),
Repeat(ref op, len) => Repeat(op.fold_with(folder), len),
- Ref(region, bk, ref place) =>
- Ref(region.fold_with(folder), bk, place.fold_with(folder)),
+ Ref(region, bk, ref place) => {
+ Ref(region.fold_with(folder), bk, place.fold_with(folder))
+ }
Len(ref place) => Len(place.fold_with(folder)),
Cast(kind, ref op, ty) => Cast(kind, op.fold_with(folder), ty.fold_with(folder)),
- BinaryOp(op, ref rhs, ref lhs) =>
- BinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder)),
- CheckedBinaryOp(op, ref rhs, ref lhs) =>
- CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder)),
+ BinaryOp(op, ref rhs, ref lhs) => {
+ BinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
+ }
+ CheckedBinaryOp(op, ref rhs, ref lhs) => {
+ CheckedBinaryOp(op, rhs.fold_with(folder), lhs.fold_with(folder))
+ }
UnaryOp(op, ref val) => UnaryOp(op, val.fold_with(folder)),
Discriminant(ref place) => Discriminant(place.fold_with(folder)),
NullaryOp(op, ty) => NullaryOp(op, ty.fold_with(folder)),
let kind = box match **kind {
AggregateKind::Array(ty) => AggregateKind::Array(ty.fold_with(folder)),
AggregateKind::Tuple => AggregateKind::Tuple,
- AggregateKind::Adt(def, v, substs, n) =>
- AggregateKind::Adt(def, v, substs.fold_with(folder), n),
- AggregateKind::Closure(id, substs) =>
- AggregateKind::Closure(id, substs.fold_with(folder)),
- AggregateKind::Generator(id, substs, movablity) =>
- AggregateKind::Generator(id, substs.fold_with(folder), movablity),
+ AggregateKind::Adt(def, v, substs, n) => {
+ AggregateKind::Adt(def, v, substs.fold_with(folder), n)
+ }
+ AggregateKind::Closure(id, substs) => {
+ AggregateKind::Closure(id, substs.fold_with(folder))
+ }
+ AggregateKind::Generator(id, substs, movablity) => {
+ AggregateKind::Generator(id, substs.fold_with(folder), movablity)
+ }
};
Aggregate(kind, fields.fold_with(folder))
}
Ref(region, _, ref place) => region.visit_with(visitor) || place.visit_with(visitor),
Len(ref place) => place.visit_with(visitor),
Cast(_, ref op, ty) => op.visit_with(visitor) || ty.visit_with(visitor),
- BinaryOp(_, ref rhs, ref lhs) |
- CheckedBinaryOp(_, ref rhs, ref lhs) =>
- rhs.visit_with(visitor) || lhs.visit_with(visitor),
+ BinaryOp(_, ref rhs, ref lhs) | CheckedBinaryOp(_, ref rhs, ref lhs) => {
+ rhs.visit_with(visitor) || lhs.visit_with(visitor)
+ }
UnaryOp(_, ref val) => val.visit_with(visitor),
Discriminant(ref place) => place.visit_with(visitor),
NullaryOp(_, ty) => ty.visit_with(visitor),
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
- Operand::Copy(ref place) |
- Operand::Move(ref place) => place.visit_with(visitor),
- Operand::Constant(ref c) => c.visit_with(visitor)
+ Operand::Copy(ref place) | Operand::Move(ref place) => place.visit_with(visitor),
+ Operand::Constant(ref c) => c.visit_with(visitor),
}
}
}
impl<'tcx, B, V, T> TypeFoldable<'tcx> for Projection<'tcx, B, V, T>
- where B: TypeFoldable<'tcx>, V: TypeFoldable<'tcx>, T: TypeFoldable<'tcx>
+where
+ B: TypeFoldable<'tcx>,
+ V: TypeFoldable<'tcx>,
+ T: TypeFoldable<'tcx>,
{
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
use mir::ProjectionElem::*;
Deref => Deref,
Field(f, ref ty) => Field(f, ty.fold_with(folder)),
Index(ref v) => Index(v.fold_with(folder)),
- ref elem => elem.clone()
+ ref elem => elem.clone(),
};
- Projection {
- base,
- elem,
- }
+ Projection { base, elem }
}
fn super_visit_with<Vs: TypeVisitor<'tcx>>(&self, visitor: &mut Vs) -> bool {
use mir::ProjectionElem::*;
- self.base.visit_with(visitor) ||
- match self.elem {
- Field(_, ref ty) => ty.visit_with(visitor),
- Index(ref v) => v.visit_with(visitor),
- _ => false
- }
+ self.base.visit_with(visitor) || match self.elem {
+ Field(_, ref ty) => ty.visit_with(visitor),
+ Index(ref v) => v.visit_with(visitor),
+ _ => false,
+ }
}
}
Constant {
span: self.span.clone(),
ty: self.ty.fold_with(folder),
- literal: self.literal.fold_with(folder)
+ literal: self.literal.fold_with(folder),
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
match *self {
Literal::Value { value } => Literal::Value {
- value: value.fold_with(folder)
+ value: value.fold_with(folder),
},
- Literal::Promoted { index } => Literal::Promoted { index }
+ Literal::Promoted { index } => Literal::Promoted { index },
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
match *self {
Literal::Value { value } => value.visit_with(visitor),
- Literal::Promoted { .. } => false
+ Literal::Promoted { .. } => false,
}
}
}