Add a method that hides the lifetime erasing boilerplate
This commit is contained in:
parent
da6f136997
commit
adb3fbb285
3 changed files with 20 additions and 25 deletions
|
@ -9,7 +9,7 @@ use rustc::mir;
|
|||
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::ty::{self, Ty, TyCtxt, TypeFoldable, Binder};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use syntax::codemap::{self, DUMMY_SP};
|
||||
|
||||
|
@ -225,6 +225,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
|
|||
self.tcx.normalize_associated_type(&substituted)
|
||||
}
|
||||
|
||||
pub fn erase_lifetimes<T>(&self, value: &Binder<T>) -> 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<u64>> {
|
||||
self.type_size_with_substs(ty, self.substs())
|
||||
}
|
||||
|
|
|
@ -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)?;
|
||||
|
|
|
@ -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(&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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue