From f4516e738b1e697aa940706ff32ca4bd96bf763a Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 27 Sep 2016 17:02:04 +0200 Subject: [PATCH] be able to find statics in other crates --- benches/helpers/miri_helper.rs | 2 +- src/bin/miri.rs | 2 +- src/interpreter/mod.rs | 16 +++++++++++++--- src/interpreter/step.rs | 23 +++++++++++++++-------- tests/compile-fail/rc.rs | 15 +++++++++++++++ 5 files changed, 45 insertions(+), 13 deletions(-) create mode 100644 tests/compile-fail/rc.rs diff --git a/benches/helpers/miri_helper.rs b/benches/helpers/miri_helper.rs index cdd1412204f..ff4087cb14a 100644 --- a/benches/helpers/miri_helper.rs +++ b/benches/helpers/miri_helper.rs @@ -58,7 +58,7 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls<'a> { let mut mir_map = MirMap { map: mir_map.map.clone() }; run_mir_passes(tcx, &mut mir_map); - bencher.borrow_mut().iter(|| { eval_main(tcx, &mir_map, node_id); }); + bencher.borrow_mut().iter(|| { eval_main(tcx, &mir_map, node_id, state.session); }); state.session.abort_if_errors(); }); diff --git a/src/bin/miri.rs b/src/bin/miri.rs index cc0132e4090..8bf6adde14b 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -75,7 +75,7 @@ impl<'a> CompilerCalls<'a> for MiriCompilerCalls { 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); + eval_main(tcx, &mir_map_copy, entry_def_id, memory_size, step_limit, stack_limit, state.session); state.session.abort_if_errors(); }); diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index 14f522d3370..e27ea18e2f4 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -6,6 +6,7 @@ use rustc::traits::Reveal; use rustc::ty::layout::{self, Layout, Size}; use rustc::ty::subst::{self, Subst, Substs}; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc::session::Session; use rustc::util::nodemap::DefIdMap; use rustc_data_structures::indexed_vec::Idx; use std::cell::RefCell; @@ -31,6 +32,10 @@ pub struct EvalContext<'a, 'tcx: 'a> { /// The results of the type checker, from rustc. tcx: TyCtxt<'a, 'tcx, 'tcx>, + /// The Session, from rustc. + /// Used to extract info from other crates + session: &'a Session, + /// A mapping from NodeIds to Mir, from rustc. Only contains MIR for crate-local items. mir_map: &'a MirMap<'tcx>, @@ -154,7 +159,7 @@ pub enum StackPopCleanup { } 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>, mir_map: &'a MirMap<'tcx>, memory_size: usize, stack_limit: usize, session: &'a Session) -> Self { EvalContext { tcx: tcx, mir_map: mir_map, @@ -163,6 +168,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { statics: HashMap::new(), stack: Vec::new(), stack_limit: stack_limit, + session: session, } } @@ -522,7 +528,10 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { .chain(nonnull.offset_after_field.iter().map(|s| s.bytes())); try!(self.assign_fields(dest, offsets, operands)); } else { - assert_eq!(operands.len(), 0); + for operand in operands { + let operand_ty = self.operand_ty(operand); + assert_eq!(self.type_size(operand_ty), 0); + } let offset = self.nonnull_offset(dest_ty, nndiscr, discrfield)?; let dest = dest.offset(offset.bytes() as isize); try!(self.memory.write_isize(dest, 0)); @@ -1146,9 +1155,10 @@ pub fn eval_main<'a, 'tcx: 'a>( memory_size: usize, step_limit: u64, stack_limit: usize, + session: &'a Session, ) { let mir = mir_map.map.get(&def_id).expect("no mir for main function"); - let mut ecx = EvalContext::new(tcx, mir_map, memory_size, stack_limit); + let mut ecx = EvalContext::new(tcx, mir_map, memory_size, stack_limit, session); let substs = subst::Substs::empty(tcx); let return_ptr = ecx.alloc_ret_ptr(mir.return_ty, substs) .expect("should at least be able to allocate space for the main function's return value"); diff --git a/src/interpreter/step.rs b/src/interpreter/step.rs index beecece0cb9..cd1e9a18117 100644 --- a/src/interpreter/step.rs +++ b/src/interpreter/step.rs @@ -200,18 +200,25 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for ConstantExtractor<'a, 'b, 'tcx> { if let mir::Lvalue::Static(def_id) = *lvalue { let substs = subst::Substs::empty(self.ecx.tcx); let span = self.span; - let node_item = self.ecx.tcx.map.get_if_local(def_id).expect("static not found"); - if let hir::map::Node::NodeItem(&hir::Item { ref node, .. }) = node_item { - if let hir::ItemStatic(_, m, _) = *node { - self.global_item(def_id, substs, span, m == hir::MutImmutable); - return; + if let Some(node_item) = self.ecx.tcx.map.get_if_local(def_id) { + if let hir::map::Node::NodeItem(&hir::Item { ref node, .. }) = node_item { + if let hir::ItemStatic(_, m, _) = *node { + self.global_item(def_id, substs, span, m == hir::MutImmutable); + return; + } else { + bug!("static def id doesn't point to static"); + } } else { - bug!("static def id doesn't point to static"); + bug!("static def id doesn't point to item"); } } else { - bug!("static def id doesn't point to item"); + let def = self.ecx.session.cstore.describe_def(def_id).expect("static not found"); + if let hir::def::Def::Static(_, mutable) = def { + self.global_item(def_id, substs, span, !mutable); + } else { + bug!("static found but isn't a static: {:?}", def); + } } - self.global_item(def_id, substs, span, false); } } } diff --git a/tests/compile-fail/rc.rs b/tests/compile-fail/rc.rs new file mode 100644 index 00000000000..001dec5b427 --- /dev/null +++ b/tests/compile-fail/rc.rs @@ -0,0 +1,15 @@ +//error-pattern: no mir for `std::result::unwrap_failed::__STATIC_FMTSTR` + +use std::cell::RefCell; +use std::rc::Rc; + +fn rc_refcell() -> i32 { + let r = Rc::new(RefCell::new(42)); + *r.borrow_mut() += 10; + let x = *r.borrow(); + x +} + +fn main() { + rc_refcell(); +}