X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_mir%2Finterpret%2Fvalidity.rs;h=8a8cc0fe1d174a3c2da6ad8fb569d53af91a5b24;hb=fff08cb04389497d254fb40948674cbbee402908;hp=072c6f4fd90e8e9641bcf2264246bc025050f2ab;hpb=6351267c1fc78ddfd9119f5378e1f79c734da994;p=rust.git diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 072c6f4fd90..8a8cc0fe1d1 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -8,7 +8,7 @@ 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::{ @@ -81,7 +81,7 @@ pub struct RefTracking { pub todo: Vec<(T, Vec)>, } -impl<'tcx, T: Copy + Eq + Hash> RefTracking { +impl RefTracking { pub fn new(op: T) -> Self { let mut ref_tracking = RefTracking { seen: FxHashSet::default(), @@ -149,17 +149,17 @@ fn wrapping_range_format(r: &RangeInclusive, max_hi: u128) -> String { } } -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, ref_tracking: Option<&'rt mut RefTracking>>, 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>, @@ -174,8 +174,7 @@ fn aggregate_field_path_elem( 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 { @@ -224,7 +223,7 @@ fn visit_elem( &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 @@ -236,13 +235,13 @@ fn visit_elem( } } -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 } @@ -252,7 +251,7 @@ fn visit_field( 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) } @@ -263,7 +262,7 @@ fn visit_variant( 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 @@ -274,7 +273,7 @@ fn visit_variant( } #[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. @@ -294,7 +293,7 @@ fn visit_value(&mut self, op: OpTy<'tcx, M::PointerTag>) -> EvalResult<'tcx> } } - 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 @@ -403,7 +402,7 @@ fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'t "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 @@ -450,7 +449,7 @@ fn visit_primitive(&mut self, value: OpTy<'tcx, M::PointerTag>) -> EvalResult<'t 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) } @@ -459,7 +458,7 @@ fn visit_scalar( &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(); @@ -527,8 +526,8 @@ fn visit_scalar( fn visit_aggregate( &mut self, op: OpTy<'tcx, M::PointerTag>, - fields: impl Iterator>, - ) -> EvalResult<'tcx> { + fields: impl Iterator>, + ) -> InterpResult<'tcx> { match op.layout.ty.sty { ty::Str => { let mplace = op.to_mem_place(); // strings are never immediate @@ -608,12 +607,12 @@ fn visit_aggregate( } } -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( @@ -622,7 +621,7 @@ pub fn validate_operand( path: Vec, ref_tracking: Option<&mut RefTracking>>, const_mode: bool, - ) -> EvalResult<'tcx> { + ) -> InterpResult<'tcx> { trace!("validate_operand: {:?}, {:?}", *op, op.layout.ty); // Construct a visitor