@@ -7,12 +7,13 @@ use rustc_apfloat::{
77 Float ,
88} ;
99use rustc_macros:: HashStable ;
10+ use rustc_span:: Span ;
1011use rustc_target:: abi:: { HasDataLayout , Size } ;
1112
1213use crate :: ty:: { ParamEnv , ScalarInt , Ty , TyCtxt } ;
1314
1415use super :: {
15- AllocId , AllocRange , ConstAllocation , InterpResult , Pointer , PointerArithmetic , Provenance ,
16+ AllocId , ConstAllocation , InterpResult , Pointer , PointerArithmetic , Provenance ,
1617 ScalarSizeMismatch ,
1718} ;
1819
@@ -25,7 +26,7 @@ pub struct ConstAlloc<'tcx> {
2526 pub ty : Ty < ' tcx > ,
2627}
2728
28- /// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
29+ /// Represents a constant value in Rust. `Scalar` is an optimization for
2930/// array length computations, enum discriminants and the pattern matching logic.
3031#[ derive( Copy , Clone , Debug , Eq , PartialEq , TyEncodable , TyDecodable , Hash ) ]
3132#[ derive( HashStable , Lift ) ]
@@ -38,9 +39,6 @@ pub enum ConstValue<'tcx> {
3839 /// Only used for ZSTs.
3940 ZeroSized ,
4041
41- /// Used only for `&[u8]` and `&str`
42- Slice { data : ConstAllocation < ' tcx > , start : usize , end : usize } ,
43-
4442 /// A value not represented/representable by `Scalar` or `Slice`
4543 ByRef {
4644 /// The backing memory of the value, may contain more memory than needed for just the value
@@ -52,13 +50,46 @@ pub enum ConstValue<'tcx> {
5250}
5351
5452#[ cfg( all( target_arch = "x86_64" , target_pointer_width = "64" ) ) ]
55- static_assert_size ! ( ConstValue <' _>, 32 ) ;
53+ static_assert_size ! ( ConstValue <' _>, 24 ) ;
5654
5755impl < ' tcx > ConstValue < ' tcx > {
56+ pub fn expect_slice ( self , tcx : TyCtxt < ' tcx > , span : Span ) -> & ' tcx [ u8 ] {
57+ let ConstValue :: ByRef { alloc, offset } = self else {
58+ span_bug ! ( span, "invalid string constant: {self:?}" )
59+ } ;
60+ assert_eq ! ( offset, Size :: ZERO ) ;
61+ let ptr_size = tcx. data_layout . pointer_size ;
62+ let ( alloc_id, offset) = alloc
63+ . 0
64+ . read_scalar ( & tcx, Size :: ZERO ..ptr_size, true )
65+ . unwrap ( )
66+ . to_pointer ( & tcx)
67+ . unwrap ( )
68+ . into_parts ( ) ;
69+ let len = alloc
70+ . 0
71+ . read_scalar ( & tcx, ptr_size..( ptr_size * 2 ) , true )
72+ . unwrap ( )
73+ . assert_bits ( ptr_size) ;
74+ match ( alloc_id, len) {
75+ ( _, 0 ) => b"" ,
76+ ( None , _) => {
77+ span_bug ! ( span, "string with {len} bytes but no alloc id" )
78+ }
79+ ( Some ( alloc_id) , _) => {
80+ let alloc = tcx. global_alloc ( alloc_id) . unwrap_memory ( ) ;
81+ alloc
82+ . inner ( )
83+ . get_bytes_strip_provenance ( & tcx, offset..( offset + Size :: from_bytes ( len) ) )
84+ . unwrap ( )
85+ }
86+ }
87+ }
88+
5889 #[ inline]
5990 pub fn try_to_scalar ( & self ) -> Option < Scalar < AllocId > > {
6091 match * self {
61- ConstValue :: ByRef { .. } | ConstValue :: Slice { .. } | ConstValue :: ZeroSized => None ,
92+ ConstValue :: ByRef { .. } | ConstValue :: ZeroSized => None ,
6293 ConstValue :: Scalar ( val) => Some ( val) ,
6394 }
6495 }
@@ -323,6 +354,13 @@ impl<Prov> Scalar<Prov> {
323354}
324355
325356impl < ' tcx , Prov : Provenance > Scalar < Prov > {
357+ pub fn size ( self ) -> Size {
358+ match self {
359+ Scalar :: Int ( s) => s. size ( ) ,
360+ Scalar :: Ptr ( _, size) => Size :: from_bytes ( size) ,
361+ }
362+ }
363+
326364 pub fn to_pointer ( self , cx : & impl HasDataLayout ) -> InterpResult < ' tcx , Pointer < Option < Prov > > > {
327365 match self
328366 . to_bits_or_ptr_internal ( cx. pointer_size ( ) )
@@ -496,18 +534,3 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
496534 Ok ( Double :: from_bits ( self . to_u64 ( ) ?. into ( ) ) )
497535 }
498536}
499-
500- /// Gets the bytes of a constant slice value.
501- pub fn get_slice_bytes < ' tcx > ( cx : & impl HasDataLayout , val : ConstValue < ' tcx > ) -> & ' tcx [ u8 ] {
502- if let ConstValue :: Slice { data, start, end } = val {
503- let len = end - start;
504- data. inner ( )
505- . get_bytes_strip_provenance (
506- cx,
507- AllocRange { start : Size :: from_bytes ( start) , size : Size :: from_bytes ( len) } ,
508- )
509- . unwrap_or_else ( |err| bug ! ( "const slice is invalid: {:?}" , err) )
510- } else {
511- bug ! ( "expected const slice, but found another const value" ) ;
512- }
513- }
0 commit comments