Skip to content

Commit 63c77f1

Browse files
committed
remove ScalarMaybeUndef::to_bits and make Scalar::to_bits private
1 parent 1fec682 commit 63c77f1

File tree

6 files changed

+46
-53
lines changed

6 files changed

+46
-53
lines changed

src/librustc/mir/interpret/value.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -382,9 +382,10 @@ impl<'tcx, Tag> Scalar<Tag> {
382382
}
383383
}
384384

385-
/// Do not call this method! Use either `assert_bits` or `force_bits`.
385+
/// This method is intentionally private!
386+
/// It is just a helper for other methods in this file.
386387
#[inline]
387-
pub fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> {
388+
fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> {
388389
match self {
389390
Scalar::Raw { data, size } => {
390391
assert_eq!(target_size.bytes(), size as u64);
@@ -405,7 +406,7 @@ impl<'tcx, Tag> Scalar<Tag> {
405406
pub fn assert_ptr(self) -> Pointer<Tag> {
406407
match self {
407408
Scalar::Ptr(p) => p,
408-
Scalar::Raw { .. } => bug!("expected a Pointer but got Raw bits")
409+
Scalar::Raw { .. } => bug!("expected a Pointer but got Raw bits"),
409410
}
410411
}
411412

@@ -586,12 +587,6 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
586587
}
587588
}
588589

589-
/// Do not call this method! Use either `assert_bits` or `force_bits`.
590-
#[inline(always)]
591-
pub fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> {
592-
self.not_undef()?.to_bits(target_size)
593-
}
594-
595590
#[inline(always)]
596591
pub fn to_bool(self) -> InterpResult<'tcx, bool> {
597592
self.not_undef()?.to_bool()

src/librustc/ty/sty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2576,7 +2576,7 @@ impl<'tcx> ConstKind<'tcx> {
25762576

25772577
#[inline]
25782578
pub fn try_to_bits(&self, size: ty::layout::Size) -> Option<u128> {
2579-
self.try_to_scalar()?.to_bits(size).ok()
2579+
if let ConstKind::Value(val) = self { val.try_to_bits(size) } else { None }
25802580
}
25812581
}
25822582

src/librustc_mir/interpret/intrinsics.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
384384
// `x % y != 0` or `y == 0` or `x == T::min_value() && y == -1`.
385385
// First, check x % y != 0 (or if that computation overflows).
386386
let (res, overflow, _ty) = self.overflowing_binary_op(BinOp::Rem, a, b)?;
387-
if overflow || res.to_bits(a.layout.size)? != 0 {
387+
if overflow || res.assert_bits(a.layout.size) != 0 {
388388
// Then, check if `b` is -1, which is the "min_value / -1" case.
389389
let minus1 = Scalar::from_int(-1, dest.layout.size);
390390
let b_scalar = b.to_scalar().unwrap();

src/librustc_mir/interpret/operand.rs

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -96,40 +96,40 @@ pub struct ImmTy<'tcx, Tag = ()> {
9696
impl<Tag: Copy> std::fmt::Display for ImmTy<'tcx, Tag> {
9797
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
9898
match &self.imm {
99-
Immediate::Scalar(ScalarMaybeUndef::Scalar(s)) => match s.to_bits(self.layout.size) {
100-
Ok(s) => {
101-
match self.layout.ty.kind {
102-
ty::Int(_) => {
103-
return write!(
104-
fmt,
105-
"{}",
106-
super::sign_extend(s, self.layout.size) as i128,
107-
);
108-
}
109-
ty::Uint(_) => return write!(fmt, "{}", s),
110-
ty::Bool if s == 0 => return fmt.write_str("false"),
111-
ty::Bool if s == 1 => return fmt.write_str("true"),
112-
ty::Char => {
113-
if let Some(c) = u32::try_from(s).ok().and_then(std::char::from_u32) {
114-
return write!(fmt, "{}", c);
115-
}
99+
// We cannot use `to_bits_or_ptr` as we do not have a `tcx`.
100+
// So we use `is_bits` and circumvent a bunch of sanity checking -- but
101+
// this is anyway only for printing.
102+
Immediate::Scalar(ScalarMaybeUndef::Scalar(s)) if s.is_ptr() => {
103+
fmt.write_str("{pointer}")
104+
}
105+
Immediate::Scalar(ScalarMaybeUndef::Scalar(s)) => {
106+
let s = s.assert_bits(self.layout.size);
107+
match self.layout.ty.kind {
108+
ty::Int(_) => {
109+
return write!(fmt, "{}", super::sign_extend(s, self.layout.size) as i128,);
110+
}
111+
ty::Uint(_) => return write!(fmt, "{}", s),
112+
ty::Bool if s == 0 => return fmt.write_str("false"),
113+
ty::Bool if s == 1 => return fmt.write_str("true"),
114+
ty::Char => {
115+
if let Some(c) = u32::try_from(s).ok().and_then(std::char::from_u32) {
116+
return write!(fmt, "{}", c);
116117
}
117-
ty::Float(ast::FloatTy::F32) => {
118-
if let Ok(u) = u32::try_from(s) {
119-
return write!(fmt, "{}", f32::from_bits(u));
120-
}
118+
}
119+
ty::Float(ast::FloatTy::F32) => {
120+
if let Ok(u) = u32::try_from(s) {
121+
return write!(fmt, "{}", f32::from_bits(u));
121122
}
122-
ty::Float(ast::FloatTy::F64) => {
123-
if let Ok(u) = u64::try_from(s) {
124-
return write!(fmt, "{}", f64::from_bits(u));
125-
}
123+
}
124+
ty::Float(ast::FloatTy::F64) => {
125+
if let Ok(u) = u64::try_from(s) {
126+
return write!(fmt, "{}", f64::from_bits(u));
126127
}
127-
_ => {}
128128
}
129-
write!(fmt, "{:x}", s)
129+
_ => {}
130130
}
131-
Err(_) => fmt.write_str("{pointer}"),
132-
},
131+
write!(fmt, "{:x}", s)
132+
}
133133
Immediate::Scalar(ScalarMaybeUndef::Undef) => fmt.write_str("{undef}"),
134134
Immediate::ScalarPair(..) => fmt.write_str("{wide pointer or tuple}"),
135135
}
@@ -205,11 +205,6 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> {
205205
pub fn from_int(i: impl Into<i128>, layout: TyLayout<'tcx>) -> Self {
206206
Self::from_scalar(Scalar::from_int(i, layout.size), layout)
207207
}
208-
209-
#[inline]
210-
pub fn to_bits(self) -> InterpResult<'tcx, u128> {
211-
self.to_scalar()?.to_bits(self.layout.size)
212-
}
213208
}
214209

215210
// Use the existing layout if given (but sanity check in debug mode),

src/librustc_mir/interpret/validity.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -361,16 +361,17 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
361361
ty::Float(_) | ty::Int(_) | ty::Uint(_) => {
362362
// NOTE: Keep this in sync with the array optimization for int/float
363363
// types below!
364-
let size = value.layout.size;
365364
let value = value.to_scalar_or_undef();
366365
if self.ref_tracking_for_consts.is_some() {
367366
// Integers/floats in CTFE: Must be scalar bits, pointers are dangerous
368-
try_validation!(
369-
value.to_bits(size),
370-
value,
371-
self.path,
372-
"initialized plain (non-pointer) bytes"
373-
);
367+
let is_bits = value.not_undef().map_or(false, |v| v.is_bits());
368+
if !is_bits {
369+
throw_validation_failure!(
370+
value,
371+
self.path,
372+
"initialized plain (non-pointer) bytes"
373+
)
374+
}
374375
} else {
375376
// At run-time, for now, we accept *anything* for these types, including
376377
// undef. We should fix that, but let's start low.

src/librustc_mir/transform/const_prop.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
557557
let left_ty = left.ty(&self.local_decls, self.tcx);
558558
let left_size_bits = self.ecx.layout_of(left_ty).ok()?.size.bits();
559559
let right_size = r.layout.size;
560-
let r_bits = r.to_scalar().and_then(|r| r.to_bits(right_size));
560+
let r_bits = r.to_scalar().ok();
561+
// This is basically `force_bits`.
562+
let r_bits = r_bits.and_then(|r| r.to_bits_or_ptr(right_size, &self.tcx).ok());
561563
if r_bits.map_or(false, |b| b >= left_size_bits as u128) {
562564
self.report_assert_as_lint(
563565
lint::builtin::ARITHMETIC_OVERFLOW,

0 commit comments

Comments
 (0)