@@ -9,9 +9,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol};
99use rustc_type_ir:: TypeVisitableExt ;
1010
1111use super :: interpret:: ReportedErrorInfo ;
12- use crate :: mir:: interpret:: {
13- AllocId , AllocRange , ConstAllocation , ErrorHandled , GlobalAlloc , Scalar , alloc_range,
14- } ;
12+ use crate :: mir:: interpret:: { AllocId , AllocRange , ErrorHandled , GlobalAlloc , Scalar , alloc_range} ;
1513use crate :: mir:: { Promoted , pretty_print_const_value} ;
1614use crate :: ty:: print:: { pretty_print_const, with_no_trimmed_paths} ;
1715use crate :: ty:: { self , ConstKind , GenericArgsRef , ScalarInt , Ty , TyCtxt } ;
@@ -32,8 +30,8 @@ pub struct ConstAlloc<'tcx> {
3230
3331/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
3432/// array length computations, enum discriminants and the pattern matching logic.
35- #[ derive( Copy , Clone , Debug , Eq , PartialEq , TyEncodable , TyDecodable , Hash ) ]
36- #[ derive( HashStable , Lift ) ]
33+ #[ derive( Copy , Clone , Debug , Eq , PartialEq , TyEncodable , TyDecodable , Lift , Hash ) ]
34+ #[ derive( HashStable ) ]
3735pub enum ConstValue < ' tcx > {
3836 /// Used for types with `layout::abi::Scalar` ABI.
3937 ///
@@ -52,10 +50,11 @@ pub enum ConstValue<'tcx> {
5250 Slice {
5351 /// The allocation storing the slice contents.
5452 /// This always points to the beginning of the allocation.
55- data : ConstAllocation < ' tcx > ,
53+ alloc_id : AllocId ,
5654 /// The metadata field of the reference.
5755 /// This is a "target usize", so we use `u64` as in the interpreter.
5856 meta : u64 ,
57+ phantom : std:: marker:: PhantomData < & ' tcx ( ) > ,
5958 } ,
6059
6160 /// A value not representable by the other variants; needs to be stored in-memory.
@@ -77,7 +76,7 @@ pub enum ConstValue<'tcx> {
7776#[ cfg( target_pointer_width = "64" ) ]
7877rustc_data_structures:: static_assert_size!( ConstValue <' _>, 24 ) ;
7978
80- impl < ' tcx > ConstValue < ' tcx > {
79+ impl ConstValue < ' _ > {
8180 #[ inline]
8281 pub fn try_to_scalar ( & self ) -> Option < Scalar > {
8382 match * self {
@@ -98,11 +97,11 @@ impl<'tcx> ConstValue<'tcx> {
9897 self . try_to_scalar_int ( ) ?. try_into ( ) . ok ( )
9998 }
10099
101- pub fn try_to_target_usize ( & self , tcx : TyCtxt < ' tcx > ) -> Option < u64 > {
100+ pub fn try_to_target_usize ( & self , tcx : TyCtxt < ' _ > ) -> Option < u64 > {
102101 Some ( self . try_to_scalar_int ( ) ?. to_target_usize ( tcx) )
103102 }
104103
105- pub fn try_to_bits_for_ty (
104+ pub fn try_to_bits_for_ty < ' tcx > (
106105 & self ,
107106 tcx : TyCtxt < ' tcx > ,
108107 typing_env : ty:: TypingEnv < ' tcx > ,
@@ -132,12 +131,15 @@ impl<'tcx> ConstValue<'tcx> {
132131 }
133132
134133 /// Must only be called on constants of type `&str` or `&[u8]`!
135- pub fn try_get_slice_bytes_for_diagnostics ( & self , tcx : TyCtxt < ' tcx > ) -> Option < & ' tcx [ u8 ] > {
136- let ( data, start, end) = match self {
134+ pub fn try_get_slice_bytes_for_diagnostics < ' tcx > (
135+ & self ,
136+ tcx : TyCtxt < ' tcx > ,
137+ ) -> Option < & ' tcx [ u8 ] > {
138+ let ( alloc_id, start, len) = match self {
137139 ConstValue :: Scalar ( _) | ConstValue :: ZeroSized => {
138140 bug ! ( "`try_get_slice_bytes` on non-slice constant" )
139141 }
140- & ConstValue :: Slice { data , meta } => ( data , 0 , meta) ,
142+ & ConstValue :: Slice { alloc_id , meta, phantom : _ } => ( alloc_id , 0 , meta) ,
141143 & ConstValue :: Indirect { alloc_id, offset } => {
142144 // The reference itself is stored behind an indirection.
143145 // Load the reference, and then load the actual slice contents.
@@ -170,26 +172,29 @@ impl<'tcx> ConstValue<'tcx> {
170172 // Non-empty slice, must have memory. We know this is a relative pointer.
171173 let ( inner_prov, offset) =
172174 ptr. into_pointer_or_addr ( ) . ok ( ) ?. prov_and_relative_offset ( ) ;
173- let data = tcx. global_alloc ( inner_prov. alloc_id ( ) ) . unwrap_memory ( ) ;
174- ( data, offset. bytes ( ) , offset. bytes ( ) + len)
175+ ( inner_prov. alloc_id ( ) , offset. bytes ( ) , len)
175176 }
176177 } ;
177178
179+ let data = tcx. global_alloc ( alloc_id) . unwrap_memory ( ) ;
180+
178181 // This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`.
179182 let start = start. try_into ( ) . unwrap ( ) ;
180- let end = end . try_into ( ) . unwrap ( ) ;
183+ let end = start + usize :: try_from ( len ) . unwrap ( ) ;
181184 Some ( data. inner ( ) . inspect_with_uninit_and_ptr_outside_interpreter ( start..end) )
182185 }
183186
184187 /// Check if a constant may contain provenance information. This is used by MIR opts.
185188 /// Can return `true` even if there is no provenance.
186- pub fn may_have_provenance ( & self , tcx : TyCtxt < ' tcx > , size : Size ) -> bool {
189+ pub fn may_have_provenance ( & self , tcx : TyCtxt < ' _ > , size : Size ) -> bool {
187190 match * self {
188191 ConstValue :: ZeroSized | ConstValue :: Scalar ( Scalar :: Int ( _) ) => return false ,
189192 ConstValue :: Scalar ( Scalar :: Ptr ( ..) ) => return true ,
190193 // It's hard to find out the part of the allocation we point to;
191194 // just conservatively check everything.
192- ConstValue :: Slice { data, meta : _ } => !data. inner ( ) . provenance ( ) . ptrs ( ) . is_empty ( ) ,
195+ ConstValue :: Slice { alloc_id, meta : _, phantom : _ } => {
196+ !tcx. global_alloc ( alloc_id) . unwrap_memory ( ) . inner ( ) . provenance ( ) . ptrs ( ) . is_empty ( )
197+ }
193198 ConstValue :: Indirect { alloc_id, offset } => !tcx
194199 . global_alloc ( alloc_id)
195200 . unwrap_memory ( )
@@ -200,7 +205,7 @@ impl<'tcx> ConstValue<'tcx> {
200205 }
201206
202207 /// Check if a constant only contains uninitialized bytes.
203- pub fn all_bytes_uninit ( & self , tcx : TyCtxt < ' tcx > ) -> bool {
208+ pub fn all_bytes_uninit ( & self , tcx : TyCtxt < ' _ > ) -> bool {
204209 let ConstValue :: Indirect { alloc_id, .. } = self else {
205210 return false ;
206211 } ;
@@ -487,9 +492,8 @@ impl<'tcx> Const<'tcx> {
487492 /// taking into account even pointer identity tests.
488493 pub fn is_deterministic ( & self ) -> bool {
489494 // Some constants may generate fresh allocations for pointers they contain,
490- // so using the same constant twice can yield two different results:
491- // - valtrees purposefully generate new allocations
492- // - ConstValue::Slice also generate new allocations
495+ // so using the same constant twice can yield two different results.
496+ // Notably, valtrees purposefully generate new allocations.
493497 match self {
494498 Const :: Ty ( _, c) => match c. kind ( ) {
495499 ty:: ConstKind :: Param ( ..) => true ,
@@ -507,11 +511,11 @@ impl<'tcx> Const<'tcx> {
507511 | ty:: ConstKind :: Placeholder ( ..) => bug ! ( ) ,
508512 } ,
509513 Const :: Unevaluated ( ..) => false ,
510- // If the same slice appears twice in the MIR, we cannot guarantee that we will
511- // give the same `AllocId` to the data.
512- Const :: Val ( ConstValue :: Slice { .. } , _) => false ,
513514 Const :: Val (
514- ConstValue :: ZeroSized | ConstValue :: Scalar ( _) | ConstValue :: Indirect { .. } ,
515+ ConstValue :: Slice { .. }
516+ | ConstValue :: ZeroSized
517+ | ConstValue :: Scalar ( _)
518+ | ConstValue :: Indirect { .. } ,
515519 _,
516520 ) => true ,
517521 }
0 commit comments