11use std:: fmt;
2+ use std:: num:: NonZero ;
23
34use either:: { Either , Left , Right } ;
45use rustc_abi:: { HasDataLayout , Size } ;
@@ -29,7 +30,7 @@ pub enum Scalar<Prov = CtfeProvenance> {
2930 /// We also store the size of the pointer, such that a `Scalar` always knows how big it is.
3031 /// The size is always the pointer size of the current target, but this is not information
3132 /// that we always have readily available.
32- Ptr ( Pointer < Prov > , u8 ) ,
33+ Ptr ( Pointer < Prov > , NonZero < u8 > ) ,
3334}
3435
3536#[ cfg( target_pointer_width = "64" ) ]
@@ -102,7 +103,8 @@ impl<Prov> From<ScalarInt> for Scalar<Prov> {
102103impl < Prov > Scalar < Prov > {
103104 #[ inline( always) ]
104105 pub fn from_pointer ( ptr : Pointer < Prov > , cx : & impl HasDataLayout ) -> Self {
105- Scalar :: Ptr ( ptr, u8:: try_from ( cx. pointer_size ( ) . bytes ( ) ) . unwrap ( ) )
106+ let ptr_size = u8:: try_from ( cx. pointer_size ( ) . bytes ( ) ) . ok ( ) . and_then ( NonZero :: new) . unwrap ( ) ;
107+ Scalar :: Ptr ( ptr, ptr_size)
106108 }
107109
108110 /// Create a Scalar from a pointer with an `Option<_>` provenance (where `None` represents a
@@ -236,17 +238,20 @@ impl<Prov> Scalar<Prov> {
236238 /// This throws UB (instead of ICEing) on a size mismatch since size mismatches can arise in
237239 /// Miri when someone declares a function that we shim (such as `malloc`) with a wrong type.
238240 #[ inline]
239- pub fn to_bits_or_ptr_internal ( self , target_size : Size ) -> Either < u128 , Pointer < Prov > > {
240- assert_ne ! ( target_size. bytes( ) , 0 , "you should never look at the bits of a ZST" ) ;
241+ pub fn to_bits_or_ptr_internal ( self , expected_size : Size ) -> Either < u128 , Pointer < Prov > > {
241242 match self {
242- Scalar :: Int ( int) => Left ( int. to_bits ( target_size ) ) ,
243+ Scalar :: Int ( int) => Left ( int. to_bits ( expected_size ) ) ,
243244 Scalar :: Ptr ( ptr, sz) => {
244- assert_eq ! (
245- target_size. bytes( ) ,
246- u64 :: from( sz) ,
247- "Scalar is a pointer but expected size {}" ,
248- target_size. bytes( )
249- ) ;
245+ let self_size = u64:: from ( sz. get ( ) ) ;
246+ if expected_size. bytes ( ) != self_size {
247+ #[ cold]
248+ fn invalid ( expected_size : u64 , self_size : u64 ) -> ! {
249+ panic ! ( "Scalar pointer has size {self_size} but expected {expected_size}" )
250+ }
251+
252+ invalid ( expected_size. bytes ( ) , self_size)
253+ }
254+
250255 Right ( ptr)
251256 }
252257 }
@@ -256,7 +261,7 @@ impl<Prov> Scalar<Prov> {
256261 pub fn size ( self ) -> Size {
257262 match self {
258263 Scalar :: Int ( int) => int. size ( ) ,
259- Scalar :: Ptr ( _ptr, sz) => Size :: from_bytes ( sz) ,
264+ Scalar :: Ptr ( _ptr, sz) => Size :: from_bytes ( sz. get ( ) ) ,
260265 }
261266 }
262267}
@@ -287,7 +292,8 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
287292 Scalar :: Int ( int) => Ok ( int) ,
288293 Scalar :: Ptr ( ptr, sz) => {
289294 if Prov :: OFFSET_IS_ADDR {
290- Ok ( ScalarInt :: try_from_uint ( ptr. offset . bytes ( ) , Size :: from_bytes ( sz) ) . unwrap ( ) )
295+ Ok ( ScalarInt :: try_from_uint ( ptr. offset . bytes ( ) , Size :: from_bytes ( sz. get ( ) ) )
296+ . unwrap ( ) )
291297 } else {
292298 // We know `offset` is relative, since `OFFSET_IS_ADDR == false`.
293299 let ( prov, offset) = ptr. into_raw_parts ( ) ;
0 commit comments