Skip to content

Commit e73f96a

Browse files
committed
make OpTy.op private, and ImmTy.imm public instead
1 parent 827a141 commit e73f96a

File tree

7 files changed

+80
-65
lines changed

7 files changed

+80
-65
lines changed

src/librustc_mir/const_eval.rs

+3-12
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ pub fn op_to_const<'tcx>(
7777
let normalized_op = if normalize {
7878
ecx.try_read_immediate(op)?
7979
} else {
80-
match op.op {
80+
match *op {
8181
Operand::Indirect(mplace) => Err(mplace),
8282
Operand::Immediate(val) => Ok(val)
8383
}
@@ -105,15 +105,6 @@ pub fn op_to_const<'tcx>(
105105
Ok(ty::Const { val, ty: op.layout.ty })
106106
}
107107

108-
pub fn lazy_const_to_op<'tcx>(
109-
ecx: &CompileTimeEvalContext<'_, '_, 'tcx>,
110-
cnst: ty::LazyConst<'tcx>,
111-
ty: ty::Ty<'tcx>,
112-
) -> EvalResult<'tcx, OpTy<'tcx>> {
113-
let op = ecx.const_value_to_op(cnst)?;
114-
Ok(OpTy { op, layout: ecx.layout_of(ty)? })
115-
}
116-
117108
fn eval_body_and_ecx<'a, 'mir, 'tcx>(
118109
tcx: TyCtxt<'a, 'tcx, 'tcx>,
119110
cid: GlobalId<'tcx>,
@@ -486,7 +477,7 @@ pub fn const_field<'a, 'tcx>(
486477
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env);
487478
let result = (|| {
488479
// get the operand again
489-
let op = lazy_const_to_op(&ecx, ty::LazyConst::Evaluated(value), value.ty)?;
480+
let op = ecx.lazy_const_to_op(ty::LazyConst::Evaluated(value), value.ty)?;
490481
// downcast
491482
let down = match variant {
492483
None => op,
@@ -512,7 +503,7 @@ pub fn const_variant_index<'a, 'tcx>(
512503
) -> EvalResult<'tcx, VariantIdx> {
513504
trace!("const_variant_index: {:?}", val);
514505
let ecx = mk_eval_cx(tcx, DUMMY_SP, param_env);
515-
let op = lazy_const_to_op(&ecx, ty::LazyConst::Evaluated(val), val.ty)?;
506+
let op = ecx.lazy_const_to_op(ty::LazyConst::Evaluated(val), val.ty)?;
516507
Ok(ecx.read_discriminant(op)?.1)
517508
}
518509

src/librustc_mir/interpret/cast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc::mir::interpret::{
99
use rustc::mir::CastKind;
1010
use rustc_apfloat::Float;
1111

12-
use super::{EvalContext, Machine, PlaceTy, OpTy, Immediate};
12+
use super::{EvalContext, Machine, PlaceTy, OpTy, ImmTy, Immediate};
1313

1414
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
1515
fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool {
@@ -372,7 +372,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
372372
assert_eq!(src.layout.fields.offset(i).bytes(), 0);
373373
assert_eq!(src_field_layout.size, src.layout.size);
374374
// just sawp out the layout
375-
OpTy { op: src.op, layout: src_field_layout }
375+
OpTy::from(ImmTy { imm: src.to_immediate(), layout: src_field_layout })
376376
}
377377
};
378378
if src_field.layout.ty == dst_field.layout.ty {

src/librustc_mir/interpret/operand.rs

+46-11
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use rustc::mir::interpret::{
1111
ConstValue, Pointer, Scalar,
1212
EvalResult, EvalErrorKind,
1313
};
14-
use super::{EvalContext, Machine, MemPlace, MPlaceTy, MemoryKind};
14+
use super::{
15+
EvalContext, Machine, AllocMap, Allocation, AllocationExtra,
16+
MemPlace, MPlaceTy, PlaceTy, Place, MemoryKind,
17+
};
1518
pub use rustc::mir::interpret::ScalarMaybeUndef;
1619

1720
/// A `Value` represents a single immediate self-contained Rust value.
@@ -112,15 +115,15 @@ impl<'tcx, Tag> Immediate<Tag> {
112115
// as input for binary and cast operations.
113116
#[derive(Copy, Clone, Debug)]
114117
pub struct ImmTy<'tcx, Tag=()> {
115-
immediate: Immediate<Tag>,
118+
crate imm: Immediate<Tag>, // ideally we'd make this private, but const_prop needs this
116119
pub layout: TyLayout<'tcx>,
117120
}
118121

119122
impl<'tcx, Tag> ::std::ops::Deref for ImmTy<'tcx, Tag> {
120123
type Target = Immediate<Tag>;
121124
#[inline(always)]
122125
fn deref(&self) -> &Immediate<Tag> {
123-
&self.immediate
126+
&self.imm
124127
}
125128
}
126129

@@ -180,7 +183,7 @@ impl<Tag> Operand<Tag> {
180183

181184
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
182185
pub struct OpTy<'tcx, Tag=()> {
183-
crate op: Operand<Tag>, // ideally we'd make this private, but const_prop needs this
186+
op: Operand<Tag>,
184187
pub layout: TyLayout<'tcx>,
185188
}
186189

@@ -206,7 +209,7 @@ impl<'tcx, Tag> From<ImmTy<'tcx, Tag>> for OpTy<'tcx, Tag> {
206209
#[inline(always)]
207210
fn from(val: ImmTy<'tcx, Tag>) -> Self {
208211
OpTy {
209-
op: Operand::Immediate(val.immediate),
212+
op: Operand::Immediate(val.imm),
210213
layout: val.layout
211214
}
212215
}
@@ -324,8 +327,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
324327
&self,
325328
op: OpTy<'tcx, M::PointerTag>
326329
) -> EvalResult<'tcx, ImmTy<'tcx, M::PointerTag>> {
327-
if let Ok(immediate) = self.try_read_immediate(op)? {
328-
Ok(ImmTy { immediate, layout: op.layout })
330+
if let Ok(imm) = self.try_read_immediate(op)? {
331+
Ok(ImmTy { imm, layout: op.layout })
329332
} else {
330333
bug!("primitive read failed for type: {:?}", op.layout.ty);
331334
}
@@ -469,6 +472,22 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
469472
Ok(OpTy { op, layout })
470473
}
471474

475+
/// Every place can be read from, so we can turm them into an operand
476+
#[inline(always)]
477+
pub fn place_to_op(
478+
&self,
479+
place: PlaceTy<'tcx, M::PointerTag>
480+
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
481+
let op = match *place {
482+
Place::Ptr(mplace) => {
483+
Operand::Indirect(mplace)
484+
}
485+
Place::Local { frame, local } =>
486+
*self.stack[frame].locals[local].access()?
487+
};
488+
Ok(OpTy { op, layout: place.layout })
489+
}
490+
472491
// Evaluate a place with the goal of reading from it. This lets us sometimes
473492
// avoid allocations.
474493
fn eval_place_to_op(
@@ -531,10 +550,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
531550
.collect()
532551
}
533552

534-
// Used when miri runs into a constant, and by CTFE.
535-
// FIXME: CTFE should use allocations, then we can make this private (embed it into
536-
// `eval_operand`, ideally).
537-
pub(crate) fn const_value_to_op(
553+
// Used when Miri runs into a constant, and (indirectly through lazy_const_to_op) by CTFE.
554+
fn const_value_to_op(
538555
&self,
539556
val: ty::LazyConst<'tcx>,
540557
) -> EvalResult<'tcx, Operand<M::PointerTag>> {
@@ -666,3 +683,21 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
666683
}
667684

668685
}
686+
687+
impl<'a, 'mir, 'tcx, M> EvalContext<'a, 'mir, 'tcx, M>
688+
where
689+
M: Machine<'a, 'mir, 'tcx, PointerTag=()>,
690+
// FIXME: Working around https://github.com/rust-lang/rust/issues/24159
691+
M::MemoryMap: AllocMap<AllocId, (MemoryKind<M::MemoryKinds>, Allocation<(), M::AllocExtra>)>,
692+
M::AllocExtra: AllocationExtra<(), M::MemoryExtra>,
693+
{
694+
// FIXME: CTFE should use allocations, then we can remove this.
695+
pub(crate) fn lazy_const_to_op(
696+
&self,
697+
cnst: ty::LazyConst<'tcx>,
698+
ty: ty::Ty<'tcx>,
699+
) -> EvalResult<'tcx, OpTy<'tcx>> {
700+
let op = self.const_value_to_op(cnst)?;
701+
Ok(OpTy { op, layout: self.layout_of(ty)? })
702+
}
703+
}

src/librustc_mir/interpret/place.rs

+5-21
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,10 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
244244
}
245245
}
246246

247-
impl<'tcx, Tag: ::std::fmt::Debug> OpTy<'tcx, Tag> {
247+
impl<'tcx, Tag: ::std::fmt::Debug + Copy> OpTy<'tcx, Tag> {
248248
#[inline(always)]
249249
pub fn try_as_mplace(self) -> Result<MPlaceTy<'tcx, Tag>, Immediate<Tag>> {
250-
match self.op {
250+
match *self {
251251
Operand::Indirect(mplace) => Ok(MPlaceTy { mplace, layout: self.layout }),
252252
Operand::Immediate(imm) => Err(imm),
253253
}
@@ -487,9 +487,9 @@ where
487487
Deref => self.deref_operand(base.into())?,
488488

489489
Index(local) => {
490-
let n = *self.frame().locals[local].access()?;
491-
let n_layout = self.layout_of(self.tcx.types.usize)?;
492-
let n = self.read_scalar(OpTy { op: n, layout: n_layout })?;
490+
let layout = self.layout_of(self.tcx.types.usize)?;
491+
let n = self.access_local(self.frame(), local, Some(layout))?;
492+
let n = self.read_scalar(n)?;
493493
let n = n.to_bits(self.tcx.data_layout.pointer_size)?;
494494
self.mplace_field(base, u64::try_from(n).unwrap())?
495495
}
@@ -991,22 +991,6 @@ where
991991
Ok(())
992992
}
993993

994-
/// Every place can be read from, so we can turm them into an operand
995-
#[inline(always)]
996-
pub fn place_to_op(
997-
&self,
998-
place: PlaceTy<'tcx, M::PointerTag>
999-
) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> {
1000-
let op = match place.place {
1001-
Place::Ptr(mplace) => {
1002-
Operand::Indirect(mplace)
1003-
}
1004-
Place::Local { frame, local } =>
1005-
*self.stack[frame].locals[local].access()?
1006-
};
1007-
Ok(OpTy { op, layout: place.layout })
1008-
}
1009-
1010994
pub fn raw_const_to_mplace(
1011995
&self,
1012996
raw: RawConst<'tcx>,

src/librustc_mir/interpret/terminator.rs

+8-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_target::spec::abi::Abi;
77

88
use rustc::mir::interpret::{EvalResult, PointerArithmetic, EvalErrorKind, Scalar};
99
use super::{
10-
EvalContext, Machine, Immediate, OpTy, PlaceTy, MPlaceTy, Operand, StackPopCleanup
10+
EvalContext, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup
1111
};
1212

1313
impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
@@ -418,8 +418,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
418418
let mut args = args.to_vec();
419419
let pointee = args[0].layout.ty.builtin_deref(true).unwrap().ty;
420420
let fake_fat_ptr_ty = self.tcx.mk_mut_ptr(pointee);
421-
args[0].layout = self.layout_of(fake_fat_ptr_ty)?.field(self, 0)?;
422-
args[0].op = Operand::Immediate(Immediate::Scalar(ptr.ptr.into())); // strip vtable
421+
args[0] = OpTy::from(ImmTy { // strip vtable
422+
layout: self.layout_of(fake_fat_ptr_ty)?.field(self, 0)?,
423+
imm: Immediate::Scalar(ptr.ptr.into())
424+
});
423425
trace!("Patched self operand to {:#?}", args[0]);
424426
// recurse with concrete function
425427
self.eval_fn_call(instance, span, caller_abi, &args, dest, ret)
@@ -448,8 +450,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
448450
_ => (instance, place),
449451
};
450452

451-
let arg = OpTy {
452-
op: Operand::Immediate(place.to_ref()),
453+
let arg = ImmTy {
454+
imm: place.to_ref(),
453455
layout: self.layout_of(self.tcx.mk_mut_ptr(place.layout.ty))?,
454456
};
455457

@@ -460,7 +462,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
460462
instance,
461463
span,
462464
Abi::Rust,
463-
&[arg],
465+
&[arg.into()],
464466
Some(dest.into()),
465467
Some(target),
466468
)

src/librustc_mir/interpret/traits.rs

+4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M>
2222
let (ty, poly_trait_ref) = self.tcx.erase_regions(&(ty, poly_trait_ref));
2323

2424
if let Some(&vtable) = self.vtables.get(&(ty, poly_trait_ref)) {
25+
// This means we guarantee that there are no duplicate vtables, we will
26+
// always use the same vtable for the same (Type, Trait) combination.
27+
// That's not what happens in rustc, but emulating per-crate deduplication
28+
// does not sound like it actually makes anything any better.
2529
return Ok(Pointer::from(vtable).with_default_tag());
2630
}
2731

src/librustc_mir/transform/const_prop.rs

+12-13
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,9 @@ use rustc::ty::layout::{
1818
HasTyCtxt, TargetDataLayout, HasDataLayout,
1919
};
2020

21-
use crate::interpret::{self, EvalContext, ScalarMaybeUndef, Immediate, OpTy, MemoryKind};
21+
use crate::interpret::{EvalContext, ScalarMaybeUndef, Immediate, OpTy, ImmTy, MemoryKind};
2222
use crate::const_eval::{
2323
CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx,
24-
lazy_const_to_op,
2524
};
2625
use crate::transform::{MirPass, MirSource};
2726

@@ -254,7 +253,7 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
254253
source_info: SourceInfo,
255254
) -> Option<Const<'tcx>> {
256255
self.ecx.tcx.span = source_info.span;
257-
match lazy_const_to_op(&self.ecx, *c.literal, c.ty) {
256+
match self.ecx.lazy_const_to_op(*c.literal, c.ty) {
258257
Ok(op) => {
259258
Some((op, c.span))
260259
},
@@ -345,15 +344,15 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
345344
Rvalue::Len(_) => None,
346345
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
347346
type_size_of(self.tcx, self.param_env, ty).and_then(|n| Some((
348-
OpTy {
349-
op: interpret::Operand::Immediate(Immediate::Scalar(
347+
ImmTy {
348+
imm: Immediate::Scalar(
350349
Scalar::Bits {
351350
bits: n as u128,
352351
size: self.tcx.data_layout.pointer_size.bytes() as u8,
353352
}.into()
354-
)),
353+
),
355354
layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
356-
},
355+
}.into(),
357356
span,
358357
)))
359358
}
@@ -388,11 +387,11 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
388387
// Now run the actual operation.
389388
this.ecx.unary_op(op, prim, arg.layout)
390389
})?;
391-
let res = OpTy {
392-
op: interpret::Operand::Immediate(Immediate::Scalar(val.into())),
390+
let res = ImmTy {
391+
imm: Immediate::Scalar(val.into()),
393392
layout: place_layout,
394393
};
395-
Some((res, span))
394+
Some((res.into(), span))
396395
}
397396
Rvalue::CheckedBinaryOp(op, ref left, ref right) |
398397
Rvalue::BinaryOp(op, ref left, ref right) => {
@@ -462,11 +461,11 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
462461
}
463462
Immediate::Scalar(val.into())
464463
};
465-
let res = OpTy {
466-
op: interpret::Operand::Immediate(val),
464+
let res = ImmTy {
465+
imm: val,
467466
layout: place_layout,
468467
};
469-
Some((res, span))
468+
Some((res.into(), span))
470469
},
471470
}
472471
}

0 commit comments

Comments
 (0)