@@ -5,7 +5,7 @@ use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt};
5
5
use rustc_span:: { Span , DUMMY_SP } ;
6
6
use rustc_target:: abi:: { HasDataLayout , Size } ;
7
7
8
- use crate :: mir:: interpret:: { alloc_range, AllocId , ConstAllocation , ErrorHandled , Scalar } ;
8
+ use crate :: mir:: interpret:: { alloc_range, AllocId , ErrorHandled , Scalar } ;
9
9
use crate :: mir:: { pretty_print_const_value, Promoted } ;
10
10
use crate :: ty:: print:: with_no_trimmed_paths;
11
11
use crate :: ty:: GenericArgsRef ;
@@ -28,8 +28,8 @@ pub struct ConstAlloc<'tcx> {
28
28
29
29
/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
30
30
/// 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 ) ]
33
33
pub enum ConstValue < ' tcx > {
34
34
/// Used for types with `layout::abi::Scalar` ABI.
35
35
///
@@ -48,10 +48,11 @@ pub enum ConstValue<'tcx> {
48
48
Slice {
49
49
/// The allocation storing the slice contents.
50
50
/// This always points to the beginning of the allocation.
51
- data : ConstAllocation < ' tcx > ,
51
+ alloc_id : AllocId ,
52
52
/// The metadata field of the reference.
53
53
/// This is a "target usize", so we use `u64` as in the interpreter.
54
54
meta : u64 ,
55
+ phantom : std:: marker:: PhantomData < & ' tcx ( ) > ,
55
56
} ,
56
57
57
58
/// A value not representable by the other variants; needs to be stored in-memory.
@@ -73,7 +74,7 @@ pub enum ConstValue<'tcx> {
73
74
#[ cfg( all( any( target_arch = "x86_64" , target_arch = "aarch64" ) , target_pointer_width = "64" ) ) ]
74
75
static_assert_size ! ( ConstValue <' _>, 24 ) ;
75
76
76
- impl < ' tcx > ConstValue < ' tcx > {
77
+ impl ConstValue < ' _ > {
77
78
#[ inline]
78
79
pub fn try_to_scalar ( & self ) -> Option < Scalar > {
79
80
match * self {
@@ -94,11 +95,11 @@ impl<'tcx> ConstValue<'tcx> {
94
95
self . try_to_scalar_int ( ) ?. try_into ( ) . ok ( )
95
96
}
96
97
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 > {
98
99
self . try_to_scalar_int ( ) ?. try_to_target_usize ( tcx) . ok ( )
99
100
}
100
101
101
- pub fn try_to_bits_for_ty (
102
+ pub fn try_to_bits_for_ty < ' tcx > (
102
103
& self ,
103
104
tcx : TyCtxt < ' tcx > ,
104
105
param_env : ty:: ParamEnv < ' tcx > ,
@@ -125,12 +126,15 @@ impl<'tcx> ConstValue<'tcx> {
125
126
}
126
127
127
128
/// 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 {
130
134
ConstValue :: Scalar ( _) | ConstValue :: ZeroSized => {
131
135
bug ! ( "`try_get_slice_bytes` on non-slice constant" )
132
136
}
133
- & ConstValue :: Slice { data , meta } => ( data , 0 , meta) ,
137
+ & ConstValue :: Slice { alloc_id , meta, phantom : _ } => ( alloc_id , 0 , meta) ,
134
138
& ConstValue :: Indirect { alloc_id, offset } => {
135
139
// The reference itself is stored behind an indirection.
136
140
// Load the reference, and then load the actual slice contents.
@@ -162,26 +166,29 @@ impl<'tcx> ConstValue<'tcx> {
162
166
}
163
167
// Non-empty slice, must have memory. We know this is a relative pointer.
164
168
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)
167
170
}
168
171
} ;
169
172
173
+ let data = tcx. global_alloc ( alloc_id) . unwrap_memory ( ) ;
174
+
170
175
// This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`.
171
176
let start = start. try_into ( ) . unwrap ( ) ;
172
- let end = end . try_into ( ) . unwrap ( ) ;
177
+ let end = start + usize :: try_from ( len ) . unwrap ( ) ;
173
178
Some ( data. inner ( ) . inspect_with_uninit_and_ptr_outside_interpreter ( start..end) )
174
179
}
175
180
176
181
/// Check if a constant may contain provenance information. This is used by MIR opts.
177
182
/// 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 {
179
184
match * self {
180
185
ConstValue :: ZeroSized | ConstValue :: Scalar ( Scalar :: Int ( _) ) => return false ,
181
186
ConstValue :: Scalar ( Scalar :: Ptr ( ..) ) => return true ,
182
187
// It's hard to find out the part of the allocation we point to;
183
188
// 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
+ }
185
192
ConstValue :: Indirect { alloc_id, offset } => !tcx
186
193
. global_alloc ( alloc_id)
187
194
. unwrap_memory ( )
@@ -424,9 +431,8 @@ impl<'tcx> Const<'tcx> {
424
431
/// taking into account even pointer identity tests.
425
432
pub fn is_deterministic ( & self ) -> bool {
426
433
// 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.
430
436
match self {
431
437
Const :: Ty ( c) => match c. kind ( ) {
432
438
ty:: ConstKind :: Param ( ..) => true ,
@@ -444,11 +450,11 @@ impl<'tcx> Const<'tcx> {
444
450
| ty:: ConstKind :: Placeholder ( ..) => bug ! ( ) ,
445
451
} ,
446
452
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 ,
450
453
Const :: Val (
451
- ConstValue :: ZeroSized | ConstValue :: Scalar ( _) | ConstValue :: Indirect { .. } ,
454
+ ConstValue :: Slice { .. }
455
+ | ConstValue :: ZeroSized
456
+ | ConstValue :: Scalar ( _)
457
+ | ConstValue :: Indirect { .. } ,
452
458
_,
453
459
) => true ,
454
460
}
0 commit comments