Skip to content

Commit bc528d9

Browse files
committed
Allow layout_of_local to also use cached layouts
1 parent 7cfb05f commit bc528d9

File tree

4 files changed

+19
-14
lines changed

4 files changed

+19
-14
lines changed

src/librustc_mir/interpret/eval_context.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -317,13 +317,16 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
317317
pub fn layout_of_local(
318318
&self,
319319
frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
320-
local: mir::Local
320+
local: mir::Local,
321+
layout: Option<TyLayout<'tcx>>,
321322
) -> EvalResult<'tcx, TyLayout<'tcx>> {
322323
let cell = &frame.locals[local].layout;
323324
if cell.get().is_none() {
325+
let layout = ::interpret::operand::from_known_layout(layout, || {
324326
let local_ty = frame.mir.local_decls[local].ty;
325327
let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs);
326-
let layout = self.layout_of(local_ty)?;
328+
self.layout_of(local_ty)
329+
})?;
327330
cell.set(Some(layout));
328331
}
329332

@@ -507,7 +510,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
507510
match local.state {
508511
LocalState::Live(_) => {
509512
// This needs to be peoperly initialized.
510-
let layout = self.layout_of_local(self.frame(), idx)?;
513+
let layout = self.layout_of_local(self.frame(), idx, None)?;
511514
local.state = LocalState::Live(self.uninit_operand(layout)?);
512515
}
513516
LocalState::Dead => {
@@ -601,7 +604,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
601604
assert!(local != mir::RETURN_PLACE, "Cannot make return place live");
602605
trace!("{:?} is now live", local);
603606

604-
let layout = self.layout_of_local(self.frame(), local)?;
607+
let layout = self.layout_of_local(self.frame(), local, None)?;
605608
let init = LocalState::Live(self.uninit_operand(layout)?);
606609
// StorageLive *always* kills the value that's currently stored
607610
Ok(mem::replace(&mut self.frame_mut().locals[local].state, init))

src/librustc_mir/interpret/operand.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ impl<'tcx, Tag> OpTy<'tcx, Tag>
227227
// Use the existing layout if given (but sanity check in debug mode),
228228
// or compute the layout.
229229
#[inline(always)]
230-
fn from_known_layout<'tcx>(
230+
pub(super) fn from_known_layout<'tcx>(
231231
layout: Option<TyLayout<'tcx>>,
232232
compute: impl FnOnce() -> EvalResult<'tcx, TyLayout<'tcx>>
233233
) -> EvalResult<'tcx, TyLayout<'tcx>> {
@@ -461,10 +461,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
461461
&self,
462462
frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>,
463463
local: mir::Local,
464+
layout: Option<TyLayout<'tcx>>,
464465
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
465466
assert_ne!(local, mir::RETURN_PLACE);
466467
let op = *frame.locals[local].access()?;
467-
let layout = self.layout_of_local(frame, local)?;
468+
let layout = self.layout_of_local(frame, local, layout)?;
468469
Ok(OpTy { op, layout })
469470
}
470471

@@ -473,14 +474,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
473474
fn eval_place_to_op(
474475
&self,
475476
mir_place: &mir::Place<'tcx>,
477+
layout: Option<TyLayout<'tcx>>,
476478
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
477479
use rustc::mir::Place::*;
478480
let op = match *mir_place {
479481
Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer),
480-
Local(local) => self.access_local(self.frame(), local)?,
482+
Local(local) => self.access_local(self.frame(), local, layout)?,
481483

482484
Projection(ref proj) => {
483-
let op = self.eval_place_to_op(&proj.base)?;
485+
let op = self.eval_place_to_op(&proj.base, None)?;
484486
self.operand_projection(op, &proj.elem)?
485487
}
486488

@@ -504,7 +506,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
504506
// FIXME: do some more logic on `move` to invalidate the old location
505507
Copy(ref place) |
506508
Move(ref place) =>
507-
self.eval_place_to_op(place)?,
509+
self.eval_place_to_op(place, layout)?,
508510

509511
Constant(ref constant) => {
510512
let layout = from_known_layout(layout, || {

src/librustc_mir/interpret/place.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -624,7 +624,7 @@ where
624624
// their layout on return.
625625
PlaceTy {
626626
place: *return_place,
627-
layout: self.layout_of_local(self.frame(), mir::RETURN_PLACE)?,
627+
layout: self.layout_of_local(self.frame(), mir::RETURN_PLACE, None)?,
628628
},
629629
None => return err!(InvalidNullPointerUsage),
630630
},
@@ -633,7 +633,7 @@ where
633633
frame: self.cur_frame(),
634634
local,
635635
},
636-
layout: self.layout_of_local(self.frame(), local)?,
636+
layout: self.layout_of_local(self.frame(), local, None)?,
637637
},
638638

639639
Projection(ref proj) => {
@@ -901,7 +901,7 @@ where
901901
// We need the layout of the local. We can NOT use the layout we got,
902902
// that might e.g., be an inner field of a struct with `Scalar` layout,
903903
// that has different alignment than the outer field.
904-
let local_layout = self.layout_of_local(&self.stack[frame], local)?;
904+
let local_layout = self.layout_of_local(&self.stack[frame], local, None)?;
905905
let ptr = self.allocate(local_layout, MemoryKind::Stack);
906906
// We don't have to validate as we can assume the local
907907
// was already valid for its type.

src/librustc_mir/interpret/terminator.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
309309
mir.spread_arg,
310310
mir.args_iter()
311311
.map(|local|
312-
(local, self.layout_of_local(self.frame(), local).unwrap().ty)
312+
(local, self.layout_of_local(self.frame(), local, None).unwrap().ty)
313313
)
314314
.collect::<Vec<_>>()
315315
);
@@ -383,7 +383,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
383383
}
384384
} else {
385385
let callee_layout =
386-
self.layout_of_local(self.frame(), mir::RETURN_PLACE)?;
386+
self.layout_of_local(self.frame(), mir::RETURN_PLACE, None)?;
387387
if !callee_layout.abi.is_uninhabited() {
388388
return err!(FunctionRetMismatch(
389389
self.tcx.types.never, callee_layout.ty

0 commit comments

Comments
 (0)