Skip to content

Commit 1d498d5

Browse files
committed
make ptr_op finally reponsible for all ops involving pointers; make ValTy constructor private
Also remove public OpTy constructors, but a pub(crate) constructor remains
1 parent ec056d5 commit 1d498d5

File tree

7 files changed

+63
-77
lines changed

7 files changed

+63
-77
lines changed

src/librustc_mir/const_eval.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -288,21 +288,17 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeEvaluator {
288288
)
289289
}
290290

291-
fn try_ptr_op<'a>(
291+
fn ptr_op<'a>(
292292
_ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
293293
_bin_op: mir::BinOp,
294-
left: Scalar,
294+
_left: Scalar,
295295
_left_layout: TyLayout<'tcx>,
296-
right: Scalar,
296+
_right: Scalar,
297297
_right_layout: TyLayout<'tcx>,
298-
) -> EvalResult<'tcx, Option<(Scalar, bool)>> {
299-
if left.is_bits() && right.is_bits() {
300-
Ok(None)
301-
} else {
302-
Err(
303-
ConstEvalError::NeedsRfc("pointer arithmetic or comparison".to_string()).into(),
304-
)
305-
}
298+
) -> EvalResult<'tcx, (Scalar, bool)> {
299+
Err(
300+
ConstEvalError::NeedsRfc("pointer arithmetic or comparison".to_string()).into(),
301+
)
306302
}
307303

308304
fn find_foreign_static<'a>(

src/librustc_mir/interpret/cast.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
4848
Misc => {
4949
let src = self.read_value(src)?;
5050
if self.type_is_fat_ptr(src_layout.ty) {
51-
match (src.value, self.type_is_fat_ptr(dest.layout.ty)) {
51+
match (*src, self.type_is_fat_ptr(dest.layout.ty)) {
5252
// pointers to extern types
5353
(Value::Scalar(_),_) |
5454
// slices and trait objects to other slices/trait objects
5555
(Value::ScalarPair(..), true) => {
5656
// No change to value
57-
self.write_value(src.value, dest)?;
57+
self.write_value(*src, dest)?;
5858
}
5959
// slices and trait objects to thin pointers (dropping the metadata)
6060
(Value::ScalarPair(data, _), false) => {

src/librustc_mir/interpret/machine.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,18 @@ pub trait Machine<'mir, 'tcx>: Clone + Eq + Hash {
6969
def_id: DefId,
7070
) -> EvalResult<'tcx, &'tcx Allocation>;
7171

72-
/// Called for all binary operations except on float types.
73-
///
74-
/// Returns `None` if the operation should be handled by the integer
75-
/// op code in order to share more code between machines
72+
/// Called for all binary operations on integer(-like) types when one operand is a pointer
73+
/// value, and for the `Offset` operation that is inherently about pointers.
7674
///
7775
/// Returns a (value, overflowed) pair if the operation succeeded
78-
fn try_ptr_op<'a>(
76+
fn ptr_op<'a>(
7977
ecx: &EvalContext<'a, 'mir, 'tcx, Self>,
8078
bin_op: mir::BinOp,
8179
left: Scalar,
8280
left_layout: TyLayout<'tcx>,
8381
right: Scalar,
8482
right_layout: TyLayout<'tcx>,
85-
) -> EvalResult<'tcx, Option<(Scalar, bool)>>;
83+
) -> EvalResult<'tcx, (Scalar, bool)>;
8684

8785
/// Heap allocations via the `box` keyword
8886
///

src/librustc_mir/interpret/operand.rs

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use std::hash::{Hash, Hasher};
1515
use std::convert::TryInto;
1616

1717
use rustc::{mir, ty};
18-
use rustc::ty::layout::{self, Size, Align, LayoutOf, TyLayout, HasDataLayout, IntegerExt};
18+
use rustc::ty::layout::{self, Size, LayoutOf, TyLayout, HasDataLayout, IntegerExt};
1919
use rustc_data_structures::indexed_vec::Idx;
2020

2121
use rustc::mir::interpret::{
@@ -85,7 +85,7 @@ impl<'tcx> Value {
8585
// as input for binary and cast operations.
8686
#[derive(Copy, Clone, Debug)]
8787
pub struct ValTy<'tcx> {
88-
pub value: Value,
88+
value: Value,
8989
pub layout: TyLayout<'tcx>,
9090
}
9191

@@ -107,16 +107,6 @@ pub enum Operand {
107107
}
108108

109109
impl Operand {
110-
#[inline]
111-
pub fn from_ptr(ptr: Pointer, align: Align) -> Self {
112-
Operand::Indirect(MemPlace::from_ptr(ptr, align))
113-
}
114-
115-
#[inline]
116-
pub fn from_scalar_value(val: Scalar) -> Self {
117-
Operand::Immediate(Value::Scalar(val.into()))
118-
}
119-
120110
#[inline]
121111
pub fn to_mem_place(self) -> MemPlace {
122112
match self {
@@ -138,7 +128,7 @@ impl Operand {
138128

139129
#[derive(Copy, Clone, Debug)]
140130
pub struct OpTy<'tcx> {
141-
crate op: Operand, // ideally we'd make this private, but we are not there yet
131+
crate op: Operand, // ideally we'd make this private, but const_prop needs this
142132
pub layout: TyLayout<'tcx>,
143133
}
144134

@@ -184,23 +174,6 @@ impl<'tcx> PartialEq for OpTy<'tcx> {
184174
}
185175
impl<'tcx> Eq for OpTy<'tcx> {}
186176

187-
impl<'tcx> OpTy<'tcx> {
188-
#[inline]
189-
pub fn from_ptr(ptr: Pointer, align: Align, layout: TyLayout<'tcx>) -> Self {
190-
OpTy { op: Operand::from_ptr(ptr, align), layout }
191-
}
192-
193-
#[inline]
194-
pub fn from_aligned_ptr(ptr: Pointer, layout: TyLayout<'tcx>) -> Self {
195-
OpTy { op: Operand::from_ptr(ptr, layout.align), layout }
196-
}
197-
198-
#[inline]
199-
pub fn from_scalar_value(val: Scalar, layout: TyLayout<'tcx>) -> Self {
200-
OpTy { op: Operand::Immediate(Value::Scalar(val.into())), layout }
201-
}
202-
}
203-
204177
// Use the existing layout if given (but sanity check in debug mode),
205178
// or compute the layout.
206179
#[inline(always)]
@@ -507,7 +480,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
507480
ConstValue::ByRef(id, alloc, offset) => {
508481
// We rely on mutability being set correctly in that allocation to prevent writes
509482
// where none should happen -- and for `static mut`, we copy on demand anyway.
510-
Ok(Operand::from_ptr(Pointer::new(id, offset), alloc.align))
483+
Ok(Operand::Indirect(MemPlace::from_ptr(Pointer::new(id, offset), alloc.align)))
511484
},
512485
ConstValue::ScalarPair(a, b) =>
513486
Ok(Operand::Immediate(Value::ScalarPair(a.into(), b))),

src/librustc_mir/interpret/operator.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
2828
right: ValTy<'tcx>,
2929
dest: PlaceTy<'tcx>,
3030
) -> EvalResult<'tcx> {
31-
let (val, overflowed) = self.binary_op(op, left, right)?;
31+
let (val, overflowed) = self.binary_op_val(op, left, right)?;
3232
let val = Value::ScalarPair(val.into(), Scalar::from_bool(overflowed).into());
3333
self.write_value(val, dest)
3434
}
@@ -42,7 +42,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
4242
right: ValTy<'tcx>,
4343
dest: PlaceTy<'tcx>,
4444
) -> EvalResult<'tcx> {
45-
let (val, _overflowed) = self.binary_op(op, left, right)?;
45+
let (val, _overflowed) = self.binary_op_val(op, left, right)?;
4646
self.write_scalar(val, dest)
4747
}
4848
}
@@ -282,16 +282,31 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
282282
Ok((val, false))
283283
}
284284

285+
/// Convenience wrapper that's useful when keeping the layout together with the
286+
/// value.
287+
#[inline]
288+
pub fn binary_op_val(
289+
&self,
290+
bin_op: mir::BinOp,
291+
left: ValTy<'tcx>,
292+
right: ValTy<'tcx>,
293+
) -> EvalResult<'tcx, (Scalar, bool)> {
294+
self.binary_op(
295+
bin_op,
296+
left.to_scalar()?, left.layout,
297+
right.to_scalar()?, right.layout,
298+
)
299+
}
300+
285301
/// Returns the result of the specified operation and whether it overflowed.
286302
pub fn binary_op(
287303
&self,
288304
bin_op: mir::BinOp,
289-
ValTy { value: left, layout: left_layout }: ValTy<'tcx>,
290-
ValTy { value: right, layout: right_layout }: ValTy<'tcx>,
305+
left: Scalar,
306+
left_layout: TyLayout<'tcx>,
307+
right: Scalar,
308+
right_layout: TyLayout<'tcx>,
291309
) -> EvalResult<'tcx, (Scalar, bool)> {
292-
let left = left.to_scalar()?;
293-
let right = right.to_scalar()?;
294-
295310
trace!("Running binary op {:?}: {:?} ({:?}), {:?} ({:?})",
296311
bin_op, left, left_layout.ty, right, right_layout.ty);
297312

@@ -322,15 +337,13 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
322337
right_layout.ty.is_fn());
323338

324339
// Handle operations that support pointer values
325-
if let Some(handled) =
326-
M::try_ptr_op(self, bin_op, left, left_layout, right, right_layout)?
327-
{
328-
return Ok(handled);
340+
if left.is_ptr() || right.is_ptr() || bin_op == mir::BinOp::Offset {
341+
return M::ptr_op(self, bin_op, left, left_layout, right, right_layout);
329342
}
330343

331344
// Everything else only works with "proper" bits
332-
let left = left.to_bits(left_layout.size)?;
333-
let right = right.to_bits(right_layout.size)?;
345+
let left = left.to_bits(left_layout.size).expect("we checked is_ptr");
346+
let right = right.to_bits(right_layout.size).expect("we checked is_ptr");
334347
self.binary_int_op(bin_op, left, left_layout, right, right_layout)
335348
}
336349
}

src/librustc_mir/interpret/terminator.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_target::spec::abi::Abi;
1717

1818
use rustc::mir::interpret::{EvalResult, PointerArithmetic, EvalErrorKind, Scalar};
1919
use super::{
20-
EvalContext, Machine, Value, OpTy, Place, PlaceTy, ValTy, Operand, StackPopCleanup
20+
EvalContext, Machine, Value, OpTy, Place, PlaceTy, Operand, StackPopCleanup
2121
};
2222

2323
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
@@ -61,8 +61,8 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
6161
// Compare using binary_op, to also support pointer values
6262
let const_int = Scalar::from_uint(const_int, discr.layout.size);
6363
let (res, _) = self.binary_op(mir::BinOp::Eq,
64-
discr,
65-
ValTy { value: Value::Scalar(const_int.into()), layout: discr.layout }
64+
discr.to_scalar()?, discr.layout,
65+
const_int, discr.layout,
6666
)?;
6767
if res.to_bool()? {
6868
target_block = targets[index];

src/librustc_mir/transform/const_prop.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc::mir::interpret::{
2222
};
2323
use rustc::ty::{TyCtxt, self, Instance};
2424
use interpret::{EvalContext, CompileTimeEvaluator, eval_promoted, mk_borrowck_eval_cx};
25-
use interpret::{Value, OpTy, MemoryKind};
25+
use interpret::{self, Value, OpTy, MemoryKind};
2626
use transform::{MirPass, MirSource};
2727
use syntax::source_map::{Span, DUMMY_SP};
2828
use rustc::ty::subst::Substs;
@@ -358,13 +358,15 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
358358
Rvalue::Len(_) => None,
359359
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
360360
type_size_of(self.tcx, self.param_env, ty).and_then(|n| Some((
361-
OpTy::from_scalar_value(
362-
Scalar::Bits {
363-
bits: n as u128,
364-
size: self.tcx.data_layout.pointer_size.bytes() as u8,
365-
},
366-
self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
367-
),
361+
OpTy {
362+
op: interpret::Operand::Immediate(Value::Scalar(
363+
Scalar::Bits {
364+
bits: n as u128,
365+
size: self.tcx.data_layout.pointer_size.bytes() as u8,
366+
}.into()
367+
)),
368+
layout: self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
369+
},
368370
span,
369371
)))
370372
}
@@ -399,7 +401,11 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
399401
// Now run the actual operation.
400402
this.ecx.unary_op(op, prim, arg.layout)
401403
})?;
402-
Some((OpTy::from_scalar_value(val, place_layout), span))
404+
let res = OpTy {
405+
op: interpret::Operand::Immediate(Value::Scalar(val.into())),
406+
layout: place_layout,
407+
};
408+
Some((res, span))
403409
}
404410
Rvalue::CheckedBinaryOp(op, ref left, ref right) |
405411
Rvalue::BinaryOp(op, ref left, ref right) => {
@@ -454,7 +460,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
454460
})?;
455461
trace!("const evaluating {:?} for {:?} and {:?}", op, left, right);
456462
let (val, overflow) = self.use_ecx(source_info, |this| {
457-
this.ecx.binary_op(op, l, r)
463+
this.ecx.binary_op_val(op, l, r)
458464
})?;
459465
let val = if let Rvalue::CheckedBinaryOp(..) = *rvalue {
460466
Value::ScalarPair(
@@ -470,7 +476,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
470476
Value::Scalar(val.into())
471477
};
472478
let res = OpTy {
473-
op: ::interpret::Operand::Immediate(val),
479+
op: interpret::Operand::Immediate(val),
474480
layout: place_layout,
475481
};
476482
Some((res, span))

0 commit comments

Comments
 (0)