From 336949410cfe143ad6ee23e01c3c603f069e5047 Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Tue, 14 Mar 2017 10:56:33 +0100 Subject: [PATCH] Add a method that hides the lifetime erasing boilerplate --- src/eval_context.rs | 7 +++++++ src/terminator/mod.rs | 18 ++++++------------ src/traits.rs | 18 ++++++------------ 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src/eval_context.rs b/src/eval_context.rs index 9b23b849fc..2d476dfc2a 100644 --- a/src/eval_context.rs +++ b/src/eval_context.rs @@ -225,6 +225,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { self.tcx.normalize_associated_type(&substituted) } + pub fn erase_lifetimes(self, value: &Binder) -> T + where T : TypeFoldable<'tcx> + { + let value = self.tcx.erase_late_bound_regions(value) + self.tcx.erase_regions(&value) + } + pub(super) fn type_size(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, Option> { self.type_size_with_substs(ty, self.substs()) } diff --git a/src/terminator/mod.rs b/src/terminator/mod.rs index b0e7b76ae1..7968272311 100644 --- a/src/terminator/mod.rs +++ b/src/terminator/mod.rs @@ -65,16 +65,14 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { let func_ty = self.operand_ty(func); let fn_def = match func_ty.sty { ty::TyFnPtr(bare_sig) => { - let bare_sig = self.tcx.erase_late_bound_regions(&bare_sig); - let bare_sig = self.tcx.erase_regions(&bare_sig); + let bare_sig = self.erase_lifetimes(&bare_sig); let fn_ptr = self.eval_operand_to_primval(func)?.to_ptr()?; let fn_def = self.memory.get_fn(fn_ptr.alloc_id)?; match fn_def { Function::Concrete(fn_def) => { // transmuting function pointers in miri is fine as long as the number of // arguments and the abi don't change. - let sig = self.tcx.erase_late_bound_regions(&fn_def.sig); - let sig = self.tcx.erase_regions(&sig); + let sig = self.erase_lifetimes(&fn_def.sig); if sig.abi != bare_sig.abi || sig.variadic != bare_sig.variadic || sig.inputs_and_output != bare_sig.inputs_and_output { @@ -82,8 +80,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { } }, Function::NonCaptureClosureAsFnPtr(fn_def) => { - let sig = self.tcx.erase_late_bound_regions(&fn_def.sig); - let sig = self.tcx.erase_regions(&sig); + let sig = self.erase_lifetimes(&fn_def.sig); assert_eq!(sig.abi, Abi::RustCall); if sig.variadic != bare_sig.variadic || sig.inputs().len() != 1 { @@ -170,8 +167,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { match fn_def { // Intrinsics can only be addressed directly Function::Concrete(FunctionDefinition { def_id, substs, sig }) if sig.abi() == Abi::RustIntrinsic => { - let sig = self.tcx.erase_late_bound_regions(&sig); - let sig = self.tcx.erase_regions(&sig); + let sig = self.erase_lifetimes(&sig); let ty = sig.output(); let layout = self.type_layout(ty)?; let (ret, target) = match destination { @@ -184,8 +180,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { }, // C functions can only be addressed directly Function::Concrete(FunctionDefinition { def_id, sig, ..}) if sig.abi() == Abi::C => { - let sig = self.tcx.erase_late_bound_regions(&sig); - let sig = self.tcx.erase_regions(&sig); + let sig = self.erase_lifetimes(&sig); let ty = sig.output(); let (ret, target) = destination.unwrap(); self.call_c_abi(def_id, arg_operands, ret, ty)?; @@ -275,8 +270,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { ) }, Function::NonCaptureClosureAsFnPtr(FunctionDefinition { def_id, substs, sig }) if sig.abi() == Abi::RustCall => { - let sig = self.tcx.erase_late_bound_regions(&sig); - let sig = self.tcx.erase_regions(&sig); + let sig = self.erase_lifetimes(&sig); let mut args = Vec::new(); for arg in arg_operands { let arg_val = self.eval_operand(arg)?; diff --git a/src/traits.rs b/src/traits.rs index 19a4f6652d..cc0be57715 100644 --- a/src/traits.rs +++ b/src/traits.rs @@ -123,8 +123,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { }, Function::DropGlue(_) => Err(EvalError::ManuallyCalledDropGlue), Function::Concrete(fn_def) => { - let sig = self.tcx.erase_late_bound_regions(&fn_def.sig); - let sig = self.tcx.erase_regions(&sig); + let sig = self.erase_lifetimes(&fn_def.sig); trace!("sig: {:#?}", sig); args[0] = ( Value::ByVal(PrimVal::Ptr(self_ptr)), @@ -133,8 +132,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { Ok((fn_def.def_id, fn_def.substs, Vec::new())) }, Function::NonCaptureClosureAsFnPtr(fn_def) => { - let sig = self.tcx.erase_late_bound_regions(&fn_def.sig); - let sig = self.tcx.erase_regions(&sig); + let sig = self.erase_lifetimes(&fn_def.sig); args.insert(0, ( Value::ByVal(PrimVal::Undef), sig.inputs()[0], @@ -146,8 +144,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { Ok((fn_def.def_id, fn_def.substs, Vec::new())) } Function::FnPtrAsTraitObject(sig) => { - let sig = self.tcx.erase_late_bound_regions(&sig); - let sig = self.tcx.erase_regions(&sig); + let sig = self.erase_lifetimes(&fn_def.sig); trace!("sig: {:#?}", sig); // the first argument was the fat ptr args.remove(0); @@ -155,14 +152,12 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { let fn_ptr = self.memory.read_ptr(self_ptr)?; let fn_def = match self.memory.get_fn(fn_ptr.alloc_id)? { Function::Concrete(fn_def) => { - let fn_def_sig = self.tcx.erase_late_bound_regions(&fn_def.sig); - let fn_def_sig = self.tcx.erase_regions(&fn_def_sig); + let fn_def_sig = self.erase_lifetimes(&fn_def.sig); assert_eq!(sig, fn_def_sig); fn_def }, Function::NonCaptureClosureAsFnPtr(fn_def) => { - let fn_def_sig = self.tcx.erase_late_bound_regions(&fn_def.sig); - let fn_def_sig = self.tcx.erase_regions(&fn_def_sig); + let fn_def_sig = self.erase_lifetimes(&fn_def.sig); args.insert(0, ( Value::ByVal(PrimVal::Undef), fn_def_sig.inputs()[0], @@ -290,8 +285,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> { ty::TyFnDef(_, _, fn_ty) => self.tcx.erase_regions(&fn_ty), _ => bug!("drop method is not a TyFnDef"), }; - let fn_ty = self.tcx.erase_late_bound_regions(&fn_ty); - let fn_ty = self.tcx.erase_regions(&fn_ty); + let fn_ty = self.erase_lifetimes(&fn_ty); // The real type is taken from the self argument in `fn drop(&mut self)` let real_ty = match fn_ty.inputs()[0].sty { ty::TyRef(_, mt) => self.monomorphize(mt.ty, substs),