Skip to content

Commit

Permalink
Add a method that hides the lifetime erasing boilerplate
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Mar 14, 2017
1 parent da6f136 commit 3369494
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 24 deletions.
7 changes: 7 additions & 0 deletions src/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand Down
18 changes: 6 additions & 12 deletions src/terminator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,22 @@ 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 {
return Err(EvalError::FunctionPointerTyMismatch(sig, bare_sig));
}
},
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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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)?;
Expand Down Expand Up @@ -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)?;
Expand Down
18 changes: 6 additions & 12 deletions src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)),
Expand All @@ -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],
Expand All @@ -146,23 +144,20 @@ 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);
self.unpack_fn_args(args)?;
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],
Expand Down Expand Up @@ -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),
Expand Down

0 comments on commit 3369494

Please sign in to comment.