1
Fork 0

Add a method that hides the lifetime erasing boilerplate

This commit is contained in:
Oliver Schneider 2017-03-14 11:12:59 +01:00
parent da6f136997
commit adb3fbb285
3 changed files with 20 additions and 25 deletions

View file

@ -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())
}

View file

@ -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)?;

View file

@ -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),