Skip to content

Commit adb3fbb

Browse files
committed
Add a method that hides the lifetime erasing boilerplate
1 parent da6f136 commit adb3fbb

File tree

3 files changed

+20
-25
lines changed

3 files changed

+20
-25
lines changed

src/eval_context.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc::mir;
99
use rustc::traits::Reveal;
1010
use rustc::ty::layout::{self, Layout, Size};
1111
use rustc::ty::subst::{self, Subst, Substs};
12-
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
12+
use rustc::ty::{self, Ty, TyCtxt, TypeFoldable, Binder};
1313
use rustc_data_structures::indexed_vec::Idx;
1414
use syntax::codemap::{self, DUMMY_SP};
1515

@@ -225,6 +225,13 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
225225
self.tcx.normalize_associated_type(&substituted)
226226
}
227227

228+
pub fn erase_lifetimes<T>(&self, value: &Binder<T>) -> T
229+
where T : TypeFoldable<'tcx>
230+
{
231+
let value = self.tcx.erase_late_bound_regions(value);
232+
self.tcx.erase_regions(&value)
233+
}
234+
228235
pub(super) fn type_size(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<u64>> {
229236
self.type_size_with_substs(ty, self.substs())
230237
}

src/terminator/mod.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -65,25 +65,22 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
6565
let func_ty = self.operand_ty(func);
6666
let fn_def = match func_ty.sty {
6767
ty::TyFnPtr(bare_sig) => {
68-
let bare_sig = self.tcx.erase_late_bound_regions(&bare_sig);
69-
let bare_sig = self.tcx.erase_regions(&bare_sig);
68+
let bare_sig = self.erase_lifetimes(&bare_sig);
7069
let fn_ptr = self.eval_operand_to_primval(func)?.to_ptr()?;
7170
let fn_def = self.memory.get_fn(fn_ptr.alloc_id)?;
7271
match fn_def {
7372
Function::Concrete(fn_def) => {
7473
// transmuting function pointers in miri is fine as long as the number of
7574
// arguments and the abi don't change.
76-
let sig = self.tcx.erase_late_bound_regions(&fn_def.sig);
77-
let sig = self.tcx.erase_regions(&sig);
75+
let sig = self.erase_lifetimes(&fn_def.sig);
7876
if sig.abi != bare_sig.abi ||
7977
sig.variadic != bare_sig.variadic ||
8078
sig.inputs_and_output != bare_sig.inputs_and_output {
8179
return Err(EvalError::FunctionPointerTyMismatch(sig, bare_sig));
8280
}
8381
},
8482
Function::NonCaptureClosureAsFnPtr(fn_def) => {
85-
let sig = self.tcx.erase_late_bound_regions(&fn_def.sig);
86-
let sig = self.tcx.erase_regions(&sig);
83+
let sig = self.erase_lifetimes(&fn_def.sig);
8784
assert_eq!(sig.abi, Abi::RustCall);
8885
if sig.variadic != bare_sig.variadic ||
8986
sig.inputs().len() != 1 {
@@ -170,8 +167,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
170167
match fn_def {
171168
// Intrinsics can only be addressed directly
172169
Function::Concrete(FunctionDefinition { def_id, substs, sig }) if sig.abi() == Abi::RustIntrinsic => {
173-
let sig = self.tcx.erase_late_bound_regions(&sig);
174-
let sig = self.tcx.erase_regions(&sig);
170+
let sig = self.erase_lifetimes(&sig);
175171
let ty = sig.output();
176172
let layout = self.type_layout(ty)?;
177173
let (ret, target) = match destination {
@@ -184,8 +180,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
184180
},
185181
// C functions can only be addressed directly
186182
Function::Concrete(FunctionDefinition { def_id, sig, ..}) if sig.abi() == Abi::C => {
187-
let sig = self.tcx.erase_late_bound_regions(&sig);
188-
let sig = self.tcx.erase_regions(&sig);
183+
let sig = self.erase_lifetimes(&sig);
189184
let ty = sig.output();
190185
let (ret, target) = destination.unwrap();
191186
self.call_c_abi(def_id, arg_operands, ret, ty)?;
@@ -275,8 +270,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
275270
)
276271
},
277272
Function::NonCaptureClosureAsFnPtr(FunctionDefinition { def_id, substs, sig }) if sig.abi() == Abi::RustCall => {
278-
let sig = self.tcx.erase_late_bound_regions(&sig);
279-
let sig = self.tcx.erase_regions(&sig);
273+
let sig = self.erase_lifetimes(&sig);
280274
let mut args = Vec::new();
281275
for arg in arg_operands {
282276
let arg_val = self.eval_operand(arg)?;

src/traits.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
123123
},
124124
Function::DropGlue(_) => Err(EvalError::ManuallyCalledDropGlue),
125125
Function::Concrete(fn_def) => {
126-
let sig = self.tcx.erase_late_bound_regions(&fn_def.sig);
127-
let sig = self.tcx.erase_regions(&sig);
126+
let sig = self.erase_lifetimes(&fn_def.sig);
128127
trace!("sig: {:#?}", sig);
129128
args[0] = (
130129
Value::ByVal(PrimVal::Ptr(self_ptr)),
@@ -133,8 +132,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
133132
Ok((fn_def.def_id, fn_def.substs, Vec::new()))
134133
},
135134
Function::NonCaptureClosureAsFnPtr(fn_def) => {
136-
let sig = self.tcx.erase_late_bound_regions(&fn_def.sig);
137-
let sig = self.tcx.erase_regions(&sig);
135+
let sig = self.erase_lifetimes(&fn_def.sig);
138136
args.insert(0, (
139137
Value::ByVal(PrimVal::Undef),
140138
sig.inputs()[0],
@@ -146,23 +144,20 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
146144
Ok((fn_def.def_id, fn_def.substs, Vec::new()))
147145
}
148146
Function::FnPtrAsTraitObject(sig) => {
149-
let sig = self.tcx.erase_late_bound_regions(&sig);
150-
let sig = self.tcx.erase_regions(&sig);
147+
let sig = self.erase_lifetimes(&sig);
151148
trace!("sig: {:#?}", sig);
152149
// the first argument was the fat ptr
153150
args.remove(0);
154151
self.unpack_fn_args(args)?;
155152
let fn_ptr = self.memory.read_ptr(self_ptr)?;
156153
let fn_def = match self.memory.get_fn(fn_ptr.alloc_id)? {
157154
Function::Concrete(fn_def) => {
158-
let fn_def_sig = self.tcx.erase_late_bound_regions(&fn_def.sig);
159-
let fn_def_sig = self.tcx.erase_regions(&fn_def_sig);
155+
let fn_def_sig = self.erase_lifetimes(&fn_def.sig);
160156
assert_eq!(sig, fn_def_sig);
161157
fn_def
162158
},
163159
Function::NonCaptureClosureAsFnPtr(fn_def) => {
164-
let fn_def_sig = self.tcx.erase_late_bound_regions(&fn_def.sig);
165-
let fn_def_sig = self.tcx.erase_regions(&fn_def_sig);
160+
let fn_def_sig = self.erase_lifetimes(&fn_def.sig);
166161
args.insert(0, (
167162
Value::ByVal(PrimVal::Undef),
168163
fn_def_sig.inputs()[0],
@@ -290,8 +285,7 @@ impl<'a, 'tcx> EvalContext<'a, 'tcx> {
290285
ty::TyFnDef(_, _, fn_ty) => self.tcx.erase_regions(&fn_ty),
291286
_ => bug!("drop method is not a TyFnDef"),
292287
};
293-
let fn_ty = self.tcx.erase_late_bound_regions(&fn_ty);
294-
let fn_ty = self.tcx.erase_regions(&fn_ty);
288+
let fn_ty = self.erase_lifetimes(&fn_ty);
295289
// The real type is taken from the self argument in `fn drop(&mut self)`
296290
let real_ty = match fn_ty.inputs()[0].sty {
297291
ty::TyRef(_, mt) => self.monomorphize(mt.ty, substs),

0 commit comments

Comments
 (0)