@@ -7,12 +7,13 @@ use rustc_apfloat::{
7
7
Float ,
8
8
} ;
9
9
use rustc_macros:: HashStable ;
10
+ use rustc_span:: Span ;
10
11
use rustc_target:: abi:: { HasDataLayout , Size } ;
11
12
12
13
use crate :: ty:: { ParamEnv , ScalarInt , Ty , TyCtxt } ;
13
14
14
15
use super :: {
15
- AllocId , AllocRange , ConstAllocation , InterpResult , Pointer , PointerArithmetic , Provenance ,
16
+ AllocId , ConstAllocation , InterpResult , Pointer , PointerArithmetic , Provenance ,
16
17
ScalarSizeMismatch ,
17
18
} ;
18
19
@@ -25,7 +26,7 @@ pub struct ConstAlloc<'tcx> {
25
26
pub ty : Ty < ' tcx > ,
26
27
}
27
28
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
29
30
/// array length computations, enum discriminants and the pattern matching logic.
30
31
#[ derive( Copy , Clone , Debug , Eq , PartialEq , TyEncodable , TyDecodable , Hash ) ]
31
32
#[ derive( HashStable , Lift ) ]
@@ -38,9 +39,6 @@ pub enum ConstValue<'tcx> {
38
39
/// Only used for ZSTs.
39
40
ZeroSized ,
40
41
41
- /// Used only for `&[u8]` and `&str`
42
- Slice { data : ConstAllocation < ' tcx > , start : usize , end : usize } ,
43
-
44
42
/// A value not represented/representable by `Scalar` or `Slice`
45
43
ByRef {
46
44
/// The backing memory of the value, may contain more memory than needed for just the value
@@ -52,13 +50,46 @@ pub enum ConstValue<'tcx> {
52
50
}
53
51
54
52
#[ cfg( all( target_arch = "x86_64" , target_pointer_width = "64" ) ) ]
55
- static_assert_size ! ( ConstValue <' _>, 32 ) ;
53
+ static_assert_size ! ( ConstValue <' _>, 24 ) ;
56
54
57
55
impl < ' 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
+
58
89
#[ inline]
59
90
pub fn try_to_scalar ( & self ) -> Option < Scalar < AllocId > > {
60
91
match * self {
61
- ConstValue :: ByRef { .. } | ConstValue :: Slice { .. } | ConstValue :: ZeroSized => None ,
92
+ ConstValue :: ByRef { .. } | ConstValue :: ZeroSized => None ,
62
93
ConstValue :: Scalar ( val) => Some ( val) ,
63
94
}
64
95
}
@@ -323,6 +354,13 @@ impl<Prov> Scalar<Prov> {
323
354
}
324
355
325
356
impl < ' 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
+
326
364
pub fn to_pointer ( self , cx : & impl HasDataLayout ) -> InterpResult < ' tcx , Pointer < Option < Prov > > > {
327
365
match self
328
366
. to_bits_or_ptr_internal ( cx. pointer_size ( ) )
@@ -496,18 +534,3 @@ impl<'tcx, Prov: Provenance> Scalar<Prov> {
496
534
Ok ( Double :: from_bits ( self . to_u64 ( ) ?. into ( ) ) )
497
535
}
498
536
}
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