Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions compiler/rustc_middle/src/mir/interpret/value.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::fmt;
use std::num::NonZero;

use either::{Either, Left, Right};
use rustc_abi::{HasDataLayout, Size};
Expand Down Expand Up @@ -29,7 +30,7 @@ pub enum Scalar<Prov = CtfeProvenance> {
/// We also store the size of the pointer, such that a `Scalar` always knows how big it is.
/// The size is always the pointer size of the current target, but this is not information
/// that we always have readily available.
Ptr(Pointer<Prov>, u8),
Ptr(Pointer<Prov>, NonZero<u8>),
}

#[cfg(target_pointer_width = "64")]
Expand Down Expand Up @@ -102,7 +103,8 @@ impl<Prov> From<ScalarInt> for Scalar<Prov> {
impl<Prov> Scalar<Prov> {
#[inline(always)]
pub fn from_pointer(ptr: Pointer<Prov>, cx: &impl HasDataLayout) -> Self {
Scalar::Ptr(ptr, u8::try_from(cx.pointer_size().bytes()).unwrap())
let ptr_size = u8::try_from(cx.pointer_size().bytes()).ok().and_then(NonZero::new).unwrap();
Scalar::Ptr(ptr, ptr_size)
}

/// Create a Scalar from a pointer with an `Option<_>` provenance (where `None` represents a
Expand Down Expand Up @@ -236,17 +238,20 @@ impl<Prov> Scalar<Prov> {
/// This throws UB (instead of ICEing) on a size mismatch since size mismatches can arise in
/// Miri when someone declares a function that we shim (such as `malloc`) with a wrong type.
#[inline]
pub fn to_bits_or_ptr_internal(self, target_size: Size) -> Either<u128, Pointer<Prov>> {
assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST");
pub fn to_bits_or_ptr_internal(self, expected_size: Size) -> Either<u128, Pointer<Prov>> {
match self {
Scalar::Int(int) => Left(int.to_bits(target_size)),
Scalar::Int(int) => Left(int.to_bits(expected_size)),
Scalar::Ptr(ptr, sz) => {
assert_eq!(
target_size.bytes(),
u64::from(sz),
"Scalar is a pointer but expected size {}",
target_size.bytes()
);
let self_size = u64::from(sz.get());
if expected_size.bytes() != self_size {
#[cold]
fn invalid(expected_size: u64, self_size: u64) -> ! {
panic!("Scalar pointer has size {self_size} but expected {expected_size}")
}

invalid(expected_size.bytes(), self_size)
}

Right(ptr)
}
}
Expand All @@ -256,7 +261,7 @@ impl<Prov> Scalar<Prov> {
pub fn size(self) -> Size {
match self {
Scalar::Int(int) => int.size(),
Scalar::Ptr(_ptr, sz) => Size::from_bytes(sz),
Scalar::Ptr(_ptr, sz) => Size::from_bytes(sz.get()),
}
}
}
Expand Down Expand Up @@ -287,7 +292,8 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
Scalar::Int(int) => Ok(int),
Scalar::Ptr(ptr, sz) => {
if Prov::OFFSET_IS_ADDR {
Ok(ScalarInt::try_from_uint(ptr.offset.bytes(), Size::from_bytes(sz)).unwrap())
Ok(ScalarInt::try_from_uint(ptr.offset.bytes(), Size::from_bytes(sz.get()))
.unwrap())
} else {
// We know `offset` is relative, since `OFFSET_IS_ADDR == false`.
let (prov, offset) = ptr.into_raw_parts();
Expand Down
20 changes: 11 additions & 9 deletions compiler/rustc_middle/src/ty/consts/int.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,15 +262,17 @@ impl ScalarInt {

/// Convert this ScalarInt to the underlying bits.
#[inline]
pub fn to_bits(self, target_size: Size) -> u128 {
assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST");
assert_eq!(
target_size.bytes(),
u64::from(self.size.get()),
"ScalarInt has size {} but expected {}",
self.size,
target_size.bytes(),
);
pub fn to_bits(self, expected_size: Size) -> u128 {
let self_size = u64::from(self.size.get());
if expected_size.bytes() != self_size {
#[cold]
fn invalid(expected_size: u64, self_size: u64) -> ! {
panic!("ScalarInt has size {self_size} but expected {expected_size}")
}

invalid(expected_size.bytes(), self_size);
}

self.check_data();
self.data
}
Expand Down
Loading