@@ -41,12 +41,20 @@ pub enum ConstValue<'tcx> {
4141 /// Only for ZSTs.
4242 ZeroSized ,
4343
44- /// Used for `&[u8]` and `&str` .
44+ /// Used for references to unsized types with slice tail .
4545 ///
46- /// This is worth an optimized representation since Rust has literals of these types.
47- /// Not having to indirect those through an `AllocId` (or two, if we used `Indirect`) has shown
48- /// measurable performance improvements on stress tests.
49- Slice { data : ConstAllocation < ' tcx > , start : usize , end : usize } ,
46+ /// This is worth an optimized representation since Rust has literals of type `&str` and
47+ /// `&[u8]`. Not having to indirect those through an `AllocId` (or two, if we used `Indirect`)
48+ /// has shown measurable performance improvements on stress tests. We then reuse this
49+ /// optimization for slice-tail types more generally during valtree-to-constval conversion.
50+ Slice {
51+ /// The allocation storing the slice contents.
52+ /// This always points to the beginning of the allocation.
53+ data : ConstAllocation < ' tcx > ,
54+ /// The metadata field of the reference.
55+ /// This is a "target usize", so we use `u64` as in the interpreter.
56+ meta : u64 ,
57+ } ,
5058
5159 /// A value not representable by the other variants; needs to be stored in-memory.
5260 ///
@@ -65,7 +73,7 @@ pub enum ConstValue<'tcx> {
6573}
6674
6775#[ cfg( all( target_arch = "x86_64" , target_pointer_width = "64" ) ) ]
68- static_assert_size ! ( ConstValue <' _>, 32 ) ;
76+ static_assert_size ! ( ConstValue <' _>, 24 ) ;
6977
7078impl < ' tcx > ConstValue < ' tcx > {
7179 #[ inline]
@@ -124,7 +132,7 @@ impl<'tcx> ConstValue<'tcx> {
124132 ConstValue :: Scalar ( _) | ConstValue :: ZeroSized => {
125133 bug ! ( "`try_get_slice_bytes` on non-slice constant" )
126134 }
127- & ConstValue :: Slice { data, start , end } => ( data, start , end ) ,
135+ & ConstValue :: Slice { data, meta } => ( data, 0 , meta ) ,
128136 & ConstValue :: Indirect { alloc_id, offset } => {
129137 // The reference itself is stored behind an indirection.
130138 // Load the reference, and then load the actual slice contents.
@@ -151,18 +159,19 @@ impl<'tcx> ConstValue<'tcx> {
151159 )
152160 . ok ( ) ?;
153161 let len = len. to_target_usize ( & tcx) . ok ( ) ?;
154- let len: usize = len. try_into ( ) . ok ( ) ?;
155162 if len == 0 {
156163 return Some ( & [ ] ) ;
157164 }
158165 // Non-empty slice, must have memory. We know this is a relative pointer.
159166 let ( inner_alloc_id, offset) = ptr. into_parts ( ) ;
160167 let data = tcx. global_alloc ( inner_alloc_id?) . unwrap_memory ( ) ;
161- ( data, offset. bytes_usize ( ) , offset. bytes_usize ( ) + len)
168+ ( data, offset. bytes ( ) , offset. bytes ( ) + len)
162169 }
163170 } ;
164171
165172 // This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`.
173+ let start = start. try_into ( ) . unwrap ( ) ;
174+ let end = end. try_into ( ) . unwrap ( ) ;
166175 Some ( data. inner ( ) . inspect_with_uninit_and_ptr_outside_interpreter ( start..end) )
167176 }
168177}
0 commit comments