Skip to content

Commit 5070dea

Browse files
committed
Lazily evaluate EvalErrorKind::*.into() calls.
eval_context.rs calls `ok_or` in multiple places with an eagerly evaluated `EvalErrorKind::*.into()` argument, which calls EvalError::from(), which calls env::var("MIRI_BACKTRACE"), which allocates a String. This code is hot enough for this to have a measurable effect on some benchmarks. This patch changes the `ok_or` calls into `ok_or_else`, thus avoiding the evaluations when they're not needed. As a result, most of the rustc-perf benchmarks get a measurable speedup, particularly the shorter-running ones, where the improvement is as high as 6%.
1 parent 23561c6 commit 5070dea

File tree

1 file changed

+5
-5
lines changed

1 file changed

+5
-5
lines changed

src/librustc_mir/interpret/eval_context.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
260260
self.param_env,
261261
def_id,
262262
substs,
263-
).ok_or(EvalErrorKind::TypeckError.into()) // turn error prop into a panic to expose associated type in const issue
263+
).ok_or_else(|| EvalErrorKind::TypeckError.into()) // turn error prop into a panic to expose associated type in const issue
264264
}
265265

266266
pub(super) fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
@@ -279,9 +279,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
279279
trace!("load mir {:?}", instance);
280280
match instance {
281281
ty::InstanceDef::Item(def_id) => {
282-
self.tcx.maybe_optimized_mir(def_id).ok_or_else(|| {
282+
self.tcx.maybe_optimized_mir(def_id).ok_or_else(||
283283
EvalErrorKind::NoMirFor(self.tcx.item_path_str(def_id)).into()
284-
})
284+
)
285285
}
286286
_ => Ok(self.tcx.instance_mir(instance)),
287287
}
@@ -691,7 +691,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
691691
self.param_env,
692692
def_id,
693693
substs,
694-
).ok_or(EvalErrorKind::TypeckError.into());
694+
).ok_or_else(|| EvalErrorKind::TypeckError.into());
695695
let fn_ptr = self.memory.create_fn_alloc(instance?);
696696
let valty = ValTy {
697697
value: Value::ByVal(PrimVal::Ptr(fn_ptr)),
@@ -1699,7 +1699,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
16991699

17001700
impl<'mir, 'tcx> Frame<'mir, 'tcx> {
17011701
pub fn get_local(&self, local: mir::Local) -> EvalResult<'tcx, Value> {
1702-
self.locals[local].ok_or(EvalErrorKind::DeadLocal.into())
1702+
self.locals[local].ok_or_else(|| EvalErrorKind::DeadLocal.into())
17031703
}
17041704

17051705
fn set_local(&mut self, local: mir::Local, value: Value) -> EvalResult<'tcx> {

0 commit comments

Comments
 (0)