rustup to rustc 1.14.0-nightly (7c69b0d5a 2016-11-01)

This commit is contained in:
Oliver Schneider
2016-11-03 10:38:08 +01:00
parent c50c6e52da
commit 19c44dab05
9 changed files with 54 additions and 101 deletions

View File

@@ -6,7 +6,6 @@ extern crate test;
use self::miri::{eval_main, run_mir_passes}; use self::miri::{eval_main, run_mir_passes};
use self::rustc::session::Session; use self::rustc::session::Session;
use self::rustc::mir::mir_map::MirMap;
use self::rustc_driver::{driver, CompilerCalls, Compilation}; use self::rustc_driver::{driver, CompilerCalls, Compilation};
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;

View File

@@ -11,7 +11,6 @@ extern crate syntax;
use miri::{eval_main, run_mir_passes}; use miri::{eval_main, run_mir_passes};
use rustc::session::Session; use rustc::session::Session;
use rustc::mir::mir_map::MirMap;
use rustc_driver::{driver, CompilerCalls, Compilation}; use rustc_driver::{driver, CompilerCalls, Compilation};
use syntax::ast::{MetaItemKind, NestedMetaItemKind}; use syntax::ast::{MetaItemKind, NestedMetaItemKind};
@@ -32,7 +31,6 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
state.session.abort_if_errors(); state.session.abort_if_errors();
let tcx = state.tcx.unwrap(); let tcx = state.tcx.unwrap();
let mir_map = state.mir_map.unwrap();
let (entry_node_id, _) = state.session.entry_fn.borrow() let (entry_node_id, _) = state.session.entry_fn.borrow()
.expect("no main or start function found"); .expect("no main or start function found");
let entry_def_id = tcx.map.local_def_id(entry_node_id); let entry_def_id = tcx.map.local_def_id(entry_node_id);
@@ -70,12 +68,8 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls {
} }
} }
let mut mir_map_copy = MirMap::new(tcx.dep_graph.clone()); run_mir_passes(tcx);
for def_id in mir_map.map.keys() { eval_main(tcx, entry_def_id, memory_size, step_limit, stack_limit);
mir_map_copy.map.insert(def_id, mir_map.map.get(&def_id).unwrap().clone());
}
run_mir_passes(tcx, &mut mir_map_copy);
eval_main(tcx, &mir_map_copy, entry_def_id, memory_size, step_limit, stack_limit);
state.session.abort_if_errors(); state.session.abort_if_errors();
}); });

View File

@@ -1,6 +1,6 @@
use std::error::Error; use std::error::Error;
use std::fmt; use std::fmt;
use rustc::mir::repr as mir; use rustc::mir;
use rustc::ty::BareFnTy; use rustc::ty::BareFnTy;
use memory::Pointer; use memory::Pointer;
use rustc_const_math::ConstMathErr; use rustc_const_math::ConstMathErr;

View File

@@ -1,17 +1,12 @@
use rustc::middle::const_val::ConstVal; use rustc::middle::const_val::ConstVal;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::hir::map::definitions::DefPathData; use rustc::hir::map::definitions::DefPathData;
use rustc::mir::mir_map::MirMap; use rustc::mir;
use rustc::mir::repr as mir;
use rustc::traits::Reveal; use rustc::traits::Reveal;
use rustc::ty::layout::{self, Layout, Size}; use rustc::ty::layout::{self, Layout, Size};
use rustc::ty::subst::{self, Subst, Substs}; use rustc::ty::subst::{self, Subst, Substs};
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
use rustc::util::nodemap::DefIdMap;
use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::indexed_vec::Idx;
use std::cell::RefCell;
use std::ops::Deref;
use std::rc::Rc;
use syntax::codemap::{self, DUMMY_SP}; use syntax::codemap::{self, DUMMY_SP};
use error::{EvalError, EvalResult}; use error::{EvalError, EvalResult};
@@ -20,6 +15,7 @@ use primval::{self, PrimVal, PrimValKind};
pub use self::value::Value; pub use self::value::Value;
use std::collections::HashMap; use std::collections::HashMap;
use std::cell::Ref;
mod step; mod step;
mod terminator; mod terminator;
@@ -27,16 +23,12 @@ mod cast;
mod vtable; mod vtable;
mod value; mod value;
pub type MirRef<'tcx> = ::std::cell::Ref<'tcx, mir::Mir<'tcx>>;
pub struct EvalContext<'a, 'tcx: 'a> { pub struct EvalContext<'a, 'tcx: 'a> {
/// The results of the type checker, from rustc. /// The results of the type checker, from rustc.
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
/// A mapping from NodeIds to Mir, from rustc. Only contains MIR for crate-local items.
mir_map: &'a MirMap<'tcx>,
/// A local cache from DefIds to Mir for non-crate-local items.
mir_cache: RefCell<DefIdMap<Rc<mir::Mir<'tcx>>>>,
/// The virtual memory system. /// The virtual memory system.
memory: Memory<'a, 'tcx>, memory: Memory<'a, 'tcx>,
@@ -44,20 +36,20 @@ pub struct EvalContext<'a, 'tcx: 'a> {
globals: HashMap<GlobalId<'tcx>, Global<'tcx>>, globals: HashMap<GlobalId<'tcx>, Global<'tcx>>,
/// The virtual call stack. /// The virtual call stack.
stack: Vec<Frame<'a, 'tcx>>, stack: Vec<Frame<'tcx>>,
/// The maximum number of stack frames allowed /// The maximum number of stack frames allowed
stack_limit: usize, stack_limit: usize,
} }
/// A stack frame. /// A stack frame.
pub struct Frame<'a, 'tcx: 'a> { pub struct Frame<'tcx> {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Function and callsite information // Function and callsite information
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// The MIR for the function called on this frame. /// The MIR for the function called on this frame.
pub mir: CachedMir<'a, 'tcx>, pub mir: MirRef<'tcx>,
/// The def_id of the current function. /// The def_id of the current function.
pub def_id: DefId, pub def_id: DefId,
@@ -125,12 +117,6 @@ pub enum LvalueExtra {
DowncastVariant(usize), DowncastVariant(usize),
} }
#[derive(Clone)]
pub enum CachedMir<'mir, 'tcx: 'mir> {
Ref(&'mir mir::Mir<'tcx>),
Owned(Rc<mir::Mir<'tcx>>)
}
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
/// Uniquely identifies a specific constant or static /// Uniquely identifies a specific constant or static
pub struct GlobalId<'tcx> { pub struct GlobalId<'tcx> {
@@ -176,11 +162,9 @@ pub enum StackPopCleanup {
} }
impl<'a, 'tcx> EvalContext<'a, 'tcx> { impl<'a, 'tcx> EvalContext<'a, 'tcx> {
pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &'a MirMap<'tcx>, memory_size: usize, stack_limit: usize) -> Self { pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, memory_size: usize, stack_limit: usize) -> Self {
EvalContext { EvalContext {
tcx: tcx, tcx: tcx,
mir_map: mir_map,
mir_cache: RefCell::new(DefIdMap()),
memory: Memory::new(&tcx.data_layout, memory_size), memory: Memory::new(&tcx.data_layout, memory_size),
globals: HashMap::new(), globals: HashMap::new(),
stack: Vec::new(), stack: Vec::new(),
@@ -211,7 +195,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
&mut self.memory &mut self.memory
} }
pub fn stack(&self) -> &[Frame<'a, 'tcx>] { pub fn stack(&self) -> &[Frame<'tcx>] {
&self.stack &self.stack
} }
@@ -292,25 +276,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
ty.is_sized(self.tcx, &self.tcx.empty_parameter_environment(), DUMMY_SP) ty.is_sized(self.tcx, &self.tcx.empty_parameter_environment(), DUMMY_SP)
} }
pub fn load_mir(&self, def_id: DefId) -> EvalResult<'tcx, CachedMir<'a, 'tcx>> { pub fn load_mir(&self, def_id: DefId) -> EvalResult<'tcx, MirRef<'tcx>> {
trace!("load mir {:?}", def_id); trace!("load mir {:?}", def_id);
if def_id.is_local() { if def_id.is_local() || self.tcx.sess.cstore.is_item_mir_available(def_id) {
Ok(CachedMir::Ref(self.mir_map.map.get(&def_id).unwrap())) Ok(self.tcx.item_mir(def_id))
} else { } else {
let mut mir_cache = self.mir_cache.borrow_mut(); Err(EvalError::NoMirFor(self.tcx.item_path_str(def_id)))
if let Some(mir) = mir_cache.get(&def_id) {
return Ok(CachedMir::Owned(mir.clone()));
}
let cs = &self.tcx.sess.cstore;
match cs.maybe_get_item_mir(self.tcx, def_id) {
Some(mir) => {
let cached = Rc::new(mir);
mir_cache.insert(def_id, cached.clone());
Ok(CachedMir::Owned(cached))
},
None => Err(EvalError::NoMirFor(self.tcx.item_path_str(def_id))),
}
} }
} }
@@ -358,7 +329,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
&mut self, &mut self,
def_id: DefId, def_id: DefId,
span: codemap::Span, span: codemap::Span,
mir: CachedMir<'a, 'tcx>, mir: MirRef<'tcx>,
substs: &'tcx Substs<'tcx>, substs: &'tcx Substs<'tcx>,
return_lvalue: Lvalue<'tcx>, return_lvalue: Lvalue<'tcx>,
return_to_block: StackPopCleanup, return_to_block: StackPopCleanup,
@@ -371,7 +342,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let locals = vec![None; num_locals]; let locals = vec![None; num_locals];
self.stack.push(Frame { self.stack.push(Frame {
mir: mir.clone(), mir: mir,
block: mir::START_BLOCK, block: mir::START_BLOCK,
return_to_block: return_to_block, return_to_block: return_to_block,
return_lvalue: return_lvalue, return_lvalue: return_lvalue,
@@ -483,7 +454,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let dest_ty = self.lvalue_ty(lvalue); let dest_ty = self.lvalue_ty(lvalue);
let dest_layout = self.type_layout(dest_ty); let dest_layout = self.type_layout(dest_ty);
use rustc::mir::repr::Rvalue::*; use rustc::mir::Rvalue::*;
match *rvalue { match *rvalue {
Use(ref operand) => { Use(ref operand) => {
let value = self.eval_operand(operand)?; let value = self.eval_operand(operand)?;
@@ -653,7 +624,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
Cast(kind, ref operand, cast_ty) => { Cast(kind, ref operand, cast_ty) => {
debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest_ty); debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest_ty);
use rustc::mir::repr::CastKind::*; use rustc::mir::CastKind::*;
match kind { match kind {
Unsize => { Unsize => {
let src = self.eval_operand(operand)?; let src = self.eval_operand(operand)?;
@@ -812,12 +783,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
} }
fn eval_operand(&mut self, op: &mir::Operand<'tcx>) -> EvalResult<'tcx, Value> { fn eval_operand(&mut self, op: &mir::Operand<'tcx>) -> EvalResult<'tcx, Value> {
use rustc::mir::repr::Operand::*; use rustc::mir::Operand::*;
match *op { match *op {
Consume(ref lvalue) => self.eval_and_read_lvalue(lvalue), Consume(ref lvalue) => self.eval_and_read_lvalue(lvalue),
Constant(mir::Constant { ref literal, ty, .. }) => { Constant(mir::Constant { ref literal, ty, .. }) => {
use rustc::mir::repr::Literal; use rustc::mir::Literal;
let value = match *literal { let value = match *literal {
Literal::Value { ref value } => self.const_to_value(value)?, Literal::Value { ref value } => self.const_to_value(value)?,
@@ -883,7 +854,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
} }
fn eval_lvalue(&mut self, mir_lvalue: &mir::Lvalue<'tcx>) -> EvalResult<'tcx, Lvalue<'tcx>> { fn eval_lvalue(&mut self, mir_lvalue: &mir::Lvalue<'tcx>) -> EvalResult<'tcx, Lvalue<'tcx>> {
use rustc::mir::repr::Lvalue::*; use rustc::mir::Lvalue::*;
let lvalue = match *mir_lvalue { let lvalue = match *mir_lvalue {
Local(mir::RETURN_POINTER) => self.frame().return_lvalue, Local(mir::RETURN_POINTER) => self.frame().return_lvalue,
@@ -922,7 +893,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
let base_ty = self.lvalue_ty(&proj.base); let base_ty = self.lvalue_ty(&proj.base);
let base_layout = self.type_layout(base_ty); let base_layout = self.type_layout(base_ty);
use rustc::mir::repr::ProjectionElem::*; use rustc::mir::ProjectionElem::*;
let (ptr, extra) = match proj.elem { let (ptr, extra) = match proj.elem {
Field(field, field_ty) => { Field(field, field_ty) => {
// FIXME(solson) // FIXME(solson)
@@ -1462,16 +1433,16 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
Ok(Value::ByVal(val)) Ok(Value::ByVal(val))
} }
fn frame(&self) -> &Frame<'a, 'tcx> { fn frame(&self) -> &Frame<'tcx> {
self.stack.last().expect("no call frames exist") self.stack.last().expect("no call frames exist")
} }
pub fn frame_mut(&mut self) -> &mut Frame<'a, 'tcx> { pub fn frame_mut(&mut self) -> &mut Frame<'tcx> {
self.stack.last_mut().expect("no call frames exist") self.stack.last_mut().expect("no call frames exist")
} }
fn mir(&self) -> CachedMir<'a, 'tcx> { fn mir(&self) -> MirRef<'tcx> {
self.frame().mir.clone() Ref::clone(&self.frame().mir)
} }
fn substs(&self) -> &'tcx Substs<'tcx> { fn substs(&self) -> &'tcx Substs<'tcx> {
@@ -1583,7 +1554,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
} }
} }
impl<'a, 'tcx: 'a> Frame<'a, 'tcx> { impl<'tcx> Frame<'tcx> {
pub fn get_local(&self, local: mir::Local) -> Option<Value> { pub fn get_local(&self, local: mir::Local) -> Option<Value> {
// Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0. // Subtract 1 because we don't store a value for the ReturnPointer, the local with index 0.
self.locals[local.index() - 1] self.locals[local.index() - 1]
@@ -1630,34 +1601,23 @@ impl<'tcx> Lvalue<'tcx> {
} }
} }
impl<'mir, 'tcx: 'mir> Deref for CachedMir<'mir, 'tcx> {
type Target = mir::Mir<'tcx>;
fn deref(&self) -> &mir::Mir<'tcx> {
match *self {
CachedMir::Ref(r) => r,
CachedMir::Owned(ref rc) => rc,
}
}
}
pub fn eval_main<'a, 'tcx: 'a>( pub fn eval_main<'a, 'tcx: 'a>(
tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir_map: &'a MirMap<'tcx>,
def_id: DefId, def_id: DefId,
memory_size: usize, memory_size: usize,
step_limit: u64, step_limit: u64,
stack_limit: usize, stack_limit: usize,
) { ) {
let mir = mir_map.map.get(&def_id).expect("no mir for main function"); let mut ecx = EvalContext::new(tcx, memory_size, stack_limit);
let mut ecx = EvalContext::new(tcx, mir_map, memory_size, stack_limit); let mir = ecx.load_mir(def_id).expect("main function's MIR not found");
ecx.push_stack_frame( ecx.push_stack_frame(
def_id, def_id,
mir.span, mir.span,
CachedMir::Ref(mir), mir,
tcx.intern_substs(&[]), tcx.intern_substs(&[]),
Lvalue::from_ptr(Pointer::zst_ptr()), Lvalue::from_ptr(Pointer::zst_ptr()),
StackPopCleanup::None StackPopCleanup::None,
).expect("could not allocate first stack frame"); ).expect("could not allocate first stack frame");
for _ in 0..step_limit { for _ in 0..step_limit {
@@ -1695,7 +1655,7 @@ fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
impl<'tcx> ::std::panic::RefUnwindSafe for Instance<'tcx> {} impl<'tcx> ::std::panic::RefUnwindSafe for Instance<'tcx> {}
impl<'tcx> fmt::Display for Instance<'tcx> { impl<'tcx> fmt::Display for Instance<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
ppaux::parameterized(f, self.1, self.0, ppaux::Ns::Value, &[]) ppaux::parameterized(f, self.1, self.0, &[])
} }
} }
err.span_note(span, &format!("inside call to {}", Instance(def_id, substs))); err.span_note(span, &format!("inside call to {}", Instance(def_id, substs)));
@@ -1703,7 +1663,7 @@ fn report(tcx: TyCtxt, ecx: &EvalContext, e: EvalError) {
err.emit(); err.emit();
} }
pub fn run_mir_passes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &mut MirMap<'tcx>) { pub fn run_mir_passes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
let mut passes = ::rustc::mir::transform::Passes::new(); let mut passes = ::rustc::mir::transform::Passes::new();
passes.push_hook(Box::new(::rustc_mir::transform::dump_mir::DumpMir)); passes.push_hook(Box::new(::rustc_mir::transform::dump_mir::DumpMir));
passes.push_pass(Box::new(::rustc_mir::transform::no_landing_pads::NoLandingPads)); passes.push_pass(Box::new(::rustc_mir::transform::no_landing_pads::NoLandingPads));
@@ -1716,7 +1676,7 @@ pub fn run_mir_passes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &mut MirMa
passes.push_pass(Box::new(::rustc_mir::transform::simplify_cfg::SimplifyCfg::new("elaborate-drops"))); passes.push_pass(Box::new(::rustc_mir::transform::simplify_cfg::SimplifyCfg::new("elaborate-drops")));
passes.push_pass(Box::new(::rustc_mir::transform::dump_mir::Marker("PreMiri"))); passes.push_pass(Box::new(::rustc_mir::transform::dump_mir::Marker("PreMiri")));
passes.run_passes(tcx, mir_map); passes.run_passes(tcx);
} }
// TODO(solson): Upstream these methods into rustc::ty::layout. // TODO(solson): Upstream these methods into rustc::ty::layout.

View File

@@ -3,21 +3,21 @@
//! The main entry point is the `step` method. //! The main entry point is the `step` method.
use super::{ use super::{
CachedMir,
GlobalId, GlobalId,
EvalContext, EvalContext,
Lvalue, Lvalue,
StackPopCleanup, StackPopCleanup,
Global, Global,
MirRef,
}; };
use error::EvalResult; use error::EvalResult;
use rustc::mir::repr as mir; use rustc::mir;
use rustc::ty::{subst, self}; use rustc::ty::{subst, self};
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::hir; use rustc::hir;
use rustc::mir::visit::{Visitor, LvalueContext}; use rustc::mir::visit::{Visitor, LvalueContext};
use std::cell::Ref;
use syntax::codemap::Span; use syntax::codemap::Span;
use std::rc::Rc;
impl<'a, 'tcx> EvalContext<'a, 'tcx> { impl<'a, 'tcx> EvalContext<'a, 'tcx> {
/// Returns true as long as there are more things to do. /// Returns true as long as there are more things to do.
@@ -38,7 +38,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
substs: self.substs(), substs: self.substs(),
def_id: self.frame().def_id, def_id: self.frame().def_id,
ecx: self, ecx: self,
mir: &mir, mir: Ref::clone(&mir),
new_constants: &mut new, new_constants: &mut new,
}.visit_statement(block, stmt, mir::Location { }.visit_statement(block, stmt, mir::Location {
block: block, block: block,
@@ -59,7 +59,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
substs: self.substs(), substs: self.substs(),
def_id: self.frame().def_id, def_id: self.frame().def_id,
ecx: self, ecx: self,
mir: &mir, mir: Ref::clone(&mir),
new_constants: &mut new, new_constants: &mut new,
}.visit_terminator(block, terminator, mir::Location { }.visit_terminator(block, terminator, mir::Location {
block: block, block: block,
@@ -76,7 +76,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx, ()> { fn statement(&mut self, stmt: &mir::Statement<'tcx>) -> EvalResult<'tcx, ()> {
trace!("{:?}", stmt); trace!("{:?}", stmt);
use rustc::mir::repr::StatementKind::*; use rustc::mir::StatementKind::*;
match stmt.kind { match stmt.kind {
Assign(ref lvalue, ref rvalue) => self.eval_rvalue_into_lvalue(rvalue, lvalue)?, Assign(ref lvalue, ref rvalue) => self.eval_rvalue_into_lvalue(rvalue, lvalue)?,
SetDiscriminant { .. } => unimplemented!(), SetDiscriminant { .. } => unimplemented!(),
@@ -110,7 +110,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
struct ConstantExtractor<'a, 'b: 'a, 'tcx: 'b> { struct ConstantExtractor<'a, 'b: 'a, 'tcx: 'b> {
span: Span, span: Span,
ecx: &'a mut EvalContext<'b, 'tcx>, ecx: &'a mut EvalContext<'b, 'tcx>,
mir: &'a mir::Mir<'tcx>, mir: MirRef<'tcx>,
def_id: DefId, def_id: DefId,
substs: &'tcx subst::Substs<'tcx>, substs: &'tcx subst::Substs<'tcx>,
new_constants: &'a mut EvalResult<'tcx, u64>, new_constants: &'a mut EvalResult<'tcx, u64>,
@@ -165,7 +165,6 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'tcx> {
} }
}, },
mir::Literal::Promoted { index } => { mir::Literal::Promoted { index } => {
let mir = self.mir.promoted[index].clone();
let cid = GlobalId { let cid = GlobalId {
def_id: self.def_id, def_id: self.def_id,
substs: self.substs, substs: self.substs,
@@ -174,8 +173,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'tcx> {
if self.ecx.globals.contains_key(&cid) { if self.ecx.globals.contains_key(&cid) {
return; return;
} }
let mir = Ref::clone(&self.mir);
let mir = Ref::map(mir, |mir| &mir.promoted[index]);
self.try(|this| { self.try(|this| {
let mir = CachedMir::Owned(Rc::new(mir));
let ty = this.ecx.monomorphize(mir.return_ty, this.substs); let ty = this.ecx.monomorphize(mir.return_ty, this.substs);
this.ecx.globals.insert(cid, Global::uninitialized(ty)); this.ecx.globals.insert(cid, Global::uninitialized(ty));
this.ecx.push_stack_frame(this.def_id, this.ecx.push_stack_frame(this.def_id,

View File

@@ -1,5 +1,5 @@
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::mir::repr as mir; use rustc::mir;
use rustc::ty::layout::Layout; use rustc::ty::layout::Layout;
use rustc::ty::subst::Substs; use rustc::ty::subst::Substs;
use rustc::ty::{self, Ty}; use rustc::ty::{self, Ty};

View File

@@ -1,5 +1,5 @@
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::mir::repr as mir; use rustc::mir;
use rustc::traits::{self, Reveal}; use rustc::traits::{self, Reveal};
use rustc::ty::fold::TypeFoldable; use rustc::ty::fold::TypeFoldable;
use rustc::ty::layout::Layout; use rustc::ty::layout::Layout;
@@ -28,7 +28,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
&mut self, &mut self,
terminator: &mir::Terminator<'tcx>, terminator: &mir::Terminator<'tcx>,
) -> EvalResult<'tcx, ()> { ) -> EvalResult<'tcx, ()> {
use rustc::mir::repr::TerminatorKind::*; use rustc::mir::TerminatorKind::*;
match terminator.kind { match terminator.kind {
Return => self.pop_stack_frame()?, Return => self.pop_stack_frame()?,
@@ -204,7 +204,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
mir, mir,
resolved_substs, resolved_substs,
return_lvalue, return_lvalue,
return_to_block return_to_block,
)?; )?;
let arg_locals = self.frame().mir.args_iter(); let arg_locals = self.frame().mir.args_iter();

View File

@@ -4,6 +4,7 @@
collections_bound, collections_bound,
rustc_private, rustc_private,
pub_restricted, pub_restricted,
cell_extras,
)] )]
// From rustc. // From rustc.
@@ -30,7 +31,6 @@ pub use error::{
}; };
pub use interpreter::{ pub use interpreter::{
CachedMir,
EvalContext, EvalContext,
Frame, Frame,
eval_main, eval_main,

View File

@@ -3,7 +3,7 @@
use std::mem::transmute; use std::mem::transmute;
use rustc::mir::repr as mir; use rustc::mir;
use error::{EvalError, EvalResult}; use error::{EvalError, EvalResult};
use memory::{AllocId, Pointer}; use memory::{AllocId, Pointer};
@@ -274,7 +274,7 @@ pub fn binary_op<'tcx>(
left: PrimVal, left: PrimVal,
right: PrimVal right: PrimVal
) -> EvalResult<'tcx, (PrimVal, bool)> { ) -> EvalResult<'tcx, (PrimVal, bool)> {
use rustc::mir::repr::BinOp::*; use rustc::mir::BinOp::*;
use self::PrimValKind::*; use self::PrimValKind::*;
match (left.try_as_ptr(), right.try_as_ptr()) { match (left.try_as_ptr(), right.try_as_ptr()) {
@@ -377,7 +377,7 @@ pub fn binary_op<'tcx>(
} }
fn unrelated_ptr_ops<'tcx>(bin_op: mir::BinOp) -> EvalResult<'tcx, PrimVal> { fn unrelated_ptr_ops<'tcx>(bin_op: mir::BinOp) -> EvalResult<'tcx, PrimVal> {
use rustc::mir::repr::BinOp::*; use rustc::mir::BinOp::*;
match bin_op { match bin_op {
Eq => Ok(PrimVal::from_bool(false)), Eq => Ok(PrimVal::from_bool(false)),
Ne => Ok(PrimVal::from_bool(true)), Ne => Ok(PrimVal::from_bool(true)),
@@ -387,7 +387,7 @@ fn unrelated_ptr_ops<'tcx>(bin_op: mir::BinOp) -> EvalResult<'tcx, PrimVal> {
} }
pub fn unary_op<'tcx>(un_op: mir::UnOp, val: PrimVal) -> EvalResult<'tcx, PrimVal> { pub fn unary_op<'tcx>(un_op: mir::UnOp, val: PrimVal) -> EvalResult<'tcx, PrimVal> {
use rustc::mir::repr::UnOp::*; use rustc::mir::UnOp::*;
use self::PrimValKind::*; use self::PrimValKind::*;
let bits = match (un_op, val.kind) { let bits = match (un_op, val.kind) {