use rustc::ty;
use rustc_data_structures::fx::FxHashSet;
use rustc::mir::interpret::{
- Scalar, AllocKind, EvalResult, InterpError, CheckInAllocMsg,
+ Scalar, GlobalAlloc, InterpResult, InterpError, CheckInAllocMsg,
};
use super::{
pub todo: Vec<(T, Vec<PathElem>)>,
}
-impl<'tcx, T: Copy + Eq + Hash> RefTracking<T> {
+impl<T: Copy + Eq + Hash> RefTracking<T> {
pub fn new(op: T) -> Self {
let mut ref_tracking = RefTracking {
seen: FxHashSet::default(),
}
}
-struct ValidityVisitor<'rt, 'a: 'rt, 'mir: 'rt, 'tcx: 'a+'rt+'mir, M: Machine<'a, 'mir, 'tcx>+'rt> {
+struct ValidityVisitor<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> {
/// The `path` may be pushed to, but the part that is present when a function
/// starts must not be changed! `visit_fields` and `visit_array` rely on
/// this stack discipline.
path: Vec<PathElem>,
ref_tracking: Option<&'rt mut RefTracking<MPlaceTy<'tcx, M::PointerTag>>>,
const_mode: bool,
- ecx: &'rt InterpretCx<'a, 'mir, 'tcx, M>,
+ ecx: &'rt InterpretCx<'mir, 'tcx, M>,
}
-impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> ValidityVisitor<'rt, 'a, 'mir, 'tcx, M> {
+impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M> {
fn aggregate_field_path_elem(
&mut self,
layout: TyLayout<'tcx>,
if let Some(upvars) = tables.upvar_list.get(&def_id) {
// Sometimes the index is beyond the number of upvars (seen
// for a generator).
- if let Some(upvar_id) = upvars.get(field) {
- let var_hir_id = upvar_id.var_path.hir_id;
+ if let Some((&var_hir_id, _)) = upvars.get_index(field) {
let var_node_id = self.ecx.tcx.hir().hir_to_node_id(var_hir_id);
if let hir::Node::Binding(pat) = self.ecx.tcx.hir().get(var_node_id) {
if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
&mut self,
new_op: OpTy<'tcx, M::PointerTag>,
elem: PathElem,
- ) -> EvalResult<'tcx> {
+ ) -> InterpResult<'tcx> {
// Remember the old state
let path_len = self.path.len();
// Perform operation
}
}
-impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>>
- ValueVisitor<'a, 'mir, 'tcx, M> for ValidityVisitor<'rt, 'a, 'mir, 'tcx, M>
+impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
+ for ValidityVisitor<'rt, 'mir, 'tcx, M>
{
type V = OpTy<'tcx, M::PointerTag>;
#[inline(always)]
- fn ecx(&self) -> &InterpretCx<'a, 'mir, 'tcx, M> {
+ fn ecx(&self) -> &InterpretCx<'mir, 'tcx, M> {
&self.ecx
}
old_op: OpTy<'tcx, M::PointerTag>,
field: usize,
new_op: OpTy<'tcx, M::PointerTag>
- ) -> EvalResult<'tcx> {
+ ) -> InterpResult<'tcx> {
let elem = self.aggregate_field_path_elem(old_op.layout, field);
self.visit_elem(new_op, elem)
}
old_op: OpTy<'tcx, M::PointerTag>,
variant_id: VariantIdx,
new_op: OpTy<'tcx, M::PointerTag>
- ) -> EvalResult<'tcx> {
+ ) -> InterpResult<'tcx> {
let name = match old_op.layout.ty.sty {
ty::Adt(adt, _) => PathElem::Variant(adt.variants[variant_id].ident.name),
// Generators also have variants
}
#[inline]
- fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
+ fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx>
{
trace!("visit_value: {:?}, {:?}", *op, op.layout);
// Translate some possible errors to something nicer.
}
}
- fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx>
+ fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> InterpResult<'tcx>
{
let value = self.ecx.read_immediate(value)?;
// Go over all the primitive types
"integer pointer in non-ZST reference", self.path);
// Skip validation entirely for some external statics
let alloc_kind = self.ecx.tcx.alloc_map.lock().get(ptr.alloc_id);
- if let Some(AllocKind::Static(did)) = alloc_kind {
+ if let Some(GlobalAlloc::Static(did)) = alloc_kind {
// `extern static` cannot be validated as they have no body.
// FIXME: Statics from other crates are also skipped.
// They might be checked at a different type, but for now we
Ok(())
}
- fn visit_uninhabited(&mut self) -> EvalResult<'tcx>
+ fn visit_uninhabited(&mut self) -> InterpResult<'tcx>
{
validation_failure!("a value of an uninhabited type", self.path)
}
&mut self,
op: OpTy<'tcx, M::PointerTag>,
layout: &layout::Scalar,
- ) -> EvalResult<'tcx> {
+ ) -> InterpResult<'tcx> {
let value = self.ecx.read_scalar(op)?;
// Determine the allowed range
let (lo, hi) = layout.valid_range.clone().into_inner();
fn visit_aggregate(
&mut self,
op: OpTy<'tcx, M::PointerTag>,
- fields: impl Iterator<Item=EvalResult<'tcx, Self::V>>,
- ) -> EvalResult<'tcx> {
+ fields: impl Iterator<Item=InterpResult<'tcx, Self::V>>,
+ ) -> InterpResult<'tcx> {
match op.layout.ty.sty {
ty::Str => {
let mplace = op.to_mem_place(); // strings are never immediate
}
}
-impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M> {
+impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpretCx<'mir, 'tcx, M> {
/// This function checks the data at `op`. `op` is assumed to cover valid memory if it
/// is an indirect operand.
/// It will error if the bits at the destination do not match the ones described by the layout.
///
- /// `ref_tracking` can be None to avoid recursive checking below references.
+ /// `ref_tracking` can be `None` to avoid recursive checking below references.
/// This also toggles between "run-time" (no recursion) and "compile-time" (with recursion)
/// validation (e.g., pointer values are fine in integers at runtime).
pub fn validate_operand(
path: Vec<PathElem>,
ref_tracking: Option<&mut RefTracking<MPlaceTy<'tcx, M::PointerTag>>>,
const_mode: bool,
- ) -> EvalResult<'tcx> {
+ ) -> InterpResult<'tcx> {
trace!("validate_operand: {:?}, {:?}", *op, op.layout.ty);
// Construct a visitor