@@ -5,7 +5,7 @@ use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt};
55use rustc_span:: { Span , DUMMY_SP } ;
66use rustc_target:: abi:: { HasDataLayout , Size } ;
77
8- use crate :: mir:: interpret:: { alloc_range, AllocId , ConstAllocation , ErrorHandled , Scalar } ;
8+ use crate :: mir:: interpret:: { alloc_range, AllocId , ErrorHandled , Scalar } ;
99use crate :: mir:: { pretty_print_const_value, Promoted } ;
1010use crate :: ty:: print:: with_no_trimmed_paths;
1111use crate :: ty:: GenericArgsRef ;
@@ -28,8 +28,8 @@ pub struct ConstAlloc<'tcx> {
2828
2929/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
3030/// array length computations, enum discriminants and the pattern matching logic.
31- #[ derive( Copy , Clone , Debug , Eq , PartialEq , TyEncodable , TyDecodable , Hash ) ]
32- #[ derive( HashStable , Lift ) ]
31+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , TyEncodable , TyDecodable , Lift , Hash ) ]
32+ #[ derive( HashStable ) ]
3333pub enum ConstValue < ' tcx > {
3434 /// Used for types with `layout::abi::Scalar` ABI.
3535 ///
@@ -48,10 +48,11 @@ pub enum ConstValue<'tcx> {
4848 Slice {
4949 /// The allocation storing the slice contents.
5050 /// This always points to the beginning of the allocation.
51- data : ConstAllocation < ' tcx > ,
51+ alloc_id : AllocId ,
5252 /// The metadata field of the reference.
5353 /// This is a "target usize", so we use `u64` as in the interpreter.
5454 meta : u64 ,
55+ phantom : std:: marker:: PhantomData < & ' tcx ( ) > ,
5556 } ,
5657
5758 /// A value not representable by the other variants; needs to be stored in-memory.
@@ -73,7 +74,7 @@ pub enum ConstValue<'tcx> {
7374#[ cfg( all( any( target_arch = "x86_64" , target_arch = "aarch64" ) , target_pointer_width = "64" ) ) ]
7475static_assert_size ! ( ConstValue <' _>, 24 ) ;
7576
76- impl < ' tcx > ConstValue < ' tcx > {
77+ impl ConstValue < ' _ > {
7778 #[ inline]
7879 pub fn try_to_scalar ( & self ) -> Option < Scalar > {
7980 match * self {
@@ -94,11 +95,11 @@ impl<'tcx> ConstValue<'tcx> {
9495 self . try_to_scalar_int ( ) ?. try_into ( ) . ok ( )
9596 }
9697
97- pub fn try_to_target_usize ( & self , tcx : TyCtxt < ' tcx > ) -> Option < u64 > {
98+ pub fn try_to_target_usize ( & self , tcx : TyCtxt < ' _ > ) -> Option < u64 > {
9899 self . try_to_scalar_int ( ) ?. try_to_target_usize ( tcx) . ok ( )
99100 }
100101
101- pub fn try_to_bits_for_ty (
102+ pub fn try_to_bits_for_ty < ' tcx > (
102103 & self ,
103104 tcx : TyCtxt < ' tcx > ,
104105 param_env : ty:: ParamEnv < ' tcx > ,
@@ -125,12 +126,15 @@ impl<'tcx> ConstValue<'tcx> {
125126 }
126127
127128 /// Must only be called on constants of type `&str` or `&[u8]`!
128- pub fn try_get_slice_bytes_for_diagnostics ( & self , tcx : TyCtxt < ' tcx > ) -> Option < & ' tcx [ u8 ] > {
129- let ( data, start, end) = match self {
129+ pub fn try_get_slice_bytes_for_diagnostics < ' tcx > (
130+ & self ,
131+ tcx : TyCtxt < ' tcx > ,
132+ ) -> Option < & ' tcx [ u8 ] > {
133+ let ( alloc_id, start, len) = match self {
130134 ConstValue :: Scalar ( _) | ConstValue :: ZeroSized => {
131135 bug ! ( "`try_get_slice_bytes` on non-slice constant" )
132136 }
133- & ConstValue :: Slice { data , meta } => ( data , 0 , meta) ,
137+ & ConstValue :: Slice { alloc_id , meta, phantom : _ } => ( alloc_id , 0 , meta) ,
134138 & ConstValue :: Indirect { alloc_id, offset } => {
135139 // The reference itself is stored behind an indirection.
136140 // Load the reference, and then load the actual slice contents.
@@ -162,26 +166,29 @@ impl<'tcx> ConstValue<'tcx> {
162166 }
163167 // Non-empty slice, must have memory. We know this is a relative pointer.
164168 let ( inner_prov, offset) = ptr. into_parts ( ) ;
165- let data = tcx. global_alloc ( inner_prov?. alloc_id ( ) ) . unwrap_memory ( ) ;
166- ( data, offset. bytes ( ) , offset. bytes ( ) + len)
169+ ( inner_prov?. alloc_id ( ) , offset. bytes ( ) , offset. bytes ( ) + len)
167170 }
168171 } ;
169172
173+ let data = tcx. global_alloc ( alloc_id) . unwrap_memory ( ) ;
174+
170175 // This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`.
171176 let start = start. try_into ( ) . unwrap ( ) ;
172- let end = end . try_into ( ) . unwrap ( ) ;
177+ let end = start + usize :: try_from ( len ) . unwrap ( ) ;
173178 Some ( data. inner ( ) . inspect_with_uninit_and_ptr_outside_interpreter ( start..end) )
174179 }
175180
176181 /// Check if a constant may contain provenance information. This is used by MIR opts.
177182 /// Can return `true` even if there is no provenance.
178- pub fn may_have_provenance ( & self , tcx : TyCtxt < ' tcx > , size : Size ) -> bool {
183+ pub fn may_have_provenance ( & self , tcx : TyCtxt < ' _ > , size : Size ) -> bool {
179184 match * self {
180185 ConstValue :: ZeroSized | ConstValue :: Scalar ( Scalar :: Int ( _) ) => return false ,
181186 ConstValue :: Scalar ( Scalar :: Ptr ( ..) ) => return true ,
182187 // It's hard to find out the part of the allocation we point to;
183188 // just conservatively check everything.
184- ConstValue :: Slice { data, meta : _ } => !data. inner ( ) . provenance ( ) . ptrs ( ) . is_empty ( ) ,
189+ ConstValue :: Slice { alloc_id, meta : _, phantom : _ } => {
190+ !tcx. global_alloc ( alloc_id) . unwrap_memory ( ) . inner ( ) . provenance ( ) . ptrs ( ) . is_empty ( )
191+ }
185192 ConstValue :: Indirect { alloc_id, offset } => !tcx
186193 . global_alloc ( alloc_id)
187194 . unwrap_memory ( )
@@ -424,9 +431,8 @@ impl<'tcx> Const<'tcx> {
424431 /// taking into account even pointer identity tests.
425432 pub fn is_deterministic ( & self ) -> bool {
426433 // Some constants may generate fresh allocations for pointers they contain,
427- // so using the same constant twice can yield two different results:
428- // - valtrees purposefully generate new allocations
429- // - ConstValue::Slice also generate new allocations
434+ // so using the same constant twice can yield two different results.
435+ // Notably, valtrees purposefully generate new allocations.
430436 match self {
431437 Const :: Ty ( c) => match c. kind ( ) {
432438 ty:: ConstKind :: Param ( ..) => true ,
@@ -444,11 +450,11 @@ impl<'tcx> Const<'tcx> {
444450 | ty:: ConstKind :: Placeholder ( ..) => bug ! ( ) ,
445451 } ,
446452 Const :: Unevaluated ( ..) => false ,
447- // If the same slice appears twice in the MIR, we cannot guarantee that we will
448- // give the same `AllocId` to the data.
449- Const :: Val ( ConstValue :: Slice { .. } , _) => false ,
450453 Const :: Val (
451- ConstValue :: ZeroSized | ConstValue :: Scalar ( _) | ConstValue :: Indirect { .. } ,
454+ ConstValue :: Slice { .. }
455+ | ConstValue :: ZeroSized
456+ | ConstValue :: Scalar ( _)
457+ | ConstValue :: Indirect { .. } ,
452458 _,
453459 ) => true ,
454460 }
0 commit comments