@@ -9,9 +9,7 @@ use rustc_span::{DUMMY_SP, Span, Symbol};
9
9
use rustc_type_ir:: TypeVisitableExt ;
10
10
11
11
use 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} ;
15
13
use crate :: mir:: { Promoted , pretty_print_const_value} ;
16
14
use crate :: ty:: print:: { pretty_print_const, with_no_trimmed_paths} ;
17
15
use crate :: ty:: { self , ConstKind , GenericArgsRef , ScalarInt , Ty , TyCtxt } ;
@@ -32,8 +30,8 @@ pub struct ConstAlloc<'tcx> {
32
30
33
31
/// Represents a constant value in Rust. `Scalar` and `Slice` are optimizations for
34
32
/// 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 ) ]
37
35
pub enum ConstValue < ' tcx > {
38
36
/// Used for types with `layout::abi::Scalar` ABI.
39
37
///
@@ -52,10 +50,11 @@ pub enum ConstValue<'tcx> {
52
50
Slice {
53
51
/// The allocation storing the slice contents.
54
52
/// This always points to the beginning of the allocation.
55
- data : ConstAllocation < ' tcx > ,
53
+ alloc_id : AllocId ,
56
54
/// The metadata field of the reference.
57
55
/// This is a "target usize", so we use `u64` as in the interpreter.
58
56
meta : u64 ,
57
+ phantom : std:: marker:: PhantomData < & ' tcx ( ) > ,
59
58
} ,
60
59
61
60
/// A value not representable by the other variants; needs to be stored in-memory.
@@ -77,7 +76,7 @@ pub enum ConstValue<'tcx> {
77
76
#[ cfg( target_pointer_width = "64" ) ]
78
77
rustc_data_structures:: static_assert_size!( ConstValue <' _>, 24 ) ;
79
78
80
- impl < ' tcx > ConstValue < ' tcx > {
79
+ impl ConstValue < ' _ > {
81
80
#[ inline]
82
81
pub fn try_to_scalar ( & self ) -> Option < Scalar > {
83
82
match * self {
@@ -98,11 +97,11 @@ impl<'tcx> ConstValue<'tcx> {
98
97
self . try_to_scalar_int ( ) ?. try_into ( ) . ok ( )
99
98
}
100
99
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 > {
102
101
Some ( self . try_to_scalar_int ( ) ?. to_target_usize ( tcx) )
103
102
}
104
103
105
- pub fn try_to_bits_for_ty (
104
+ pub fn try_to_bits_for_ty < ' tcx > (
106
105
& self ,
107
106
tcx : TyCtxt < ' tcx > ,
108
107
typing_env : ty:: TypingEnv < ' tcx > ,
@@ -132,12 +131,15 @@ impl<'tcx> ConstValue<'tcx> {
132
131
}
133
132
134
133
/// 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 {
137
139
ConstValue :: Scalar ( _) | ConstValue :: ZeroSized => {
138
140
bug ! ( "`try_get_slice_bytes` on non-slice constant" )
139
141
}
140
- & ConstValue :: Slice { data , meta } => ( data , 0 , meta) ,
142
+ & ConstValue :: Slice { alloc_id , meta, phantom : _ } => ( alloc_id , 0 , meta) ,
141
143
& ConstValue :: Indirect { alloc_id, offset } => {
142
144
// The reference itself is stored behind an indirection.
143
145
// Load the reference, and then load the actual slice contents.
@@ -170,26 +172,29 @@ impl<'tcx> ConstValue<'tcx> {
170
172
// Non-empty slice, must have memory. We know this is a relative pointer.
171
173
let ( inner_prov, offset) =
172
174
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)
175
176
}
176
177
} ;
177
178
179
+ let data = tcx. global_alloc ( alloc_id) . unwrap_memory ( ) ;
180
+
178
181
// This is for diagnostics only, so we are okay to use `inspect_with_uninit_and_ptr_outside_interpreter`.
179
182
let start = start. try_into ( ) . unwrap ( ) ;
180
- let end = end . try_into ( ) . unwrap ( ) ;
183
+ let end = start + usize :: try_from ( len ) . unwrap ( ) ;
181
184
Some ( data. inner ( ) . inspect_with_uninit_and_ptr_outside_interpreter ( start..end) )
182
185
}
183
186
184
187
/// Check if a constant may contain provenance information. This is used by MIR opts.
185
188
/// 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 {
187
190
match * self {
188
191
ConstValue :: ZeroSized | ConstValue :: Scalar ( Scalar :: Int ( _) ) => return false ,
189
192
ConstValue :: Scalar ( Scalar :: Ptr ( ..) ) => return true ,
190
193
// It's hard to find out the part of the allocation we point to;
191
194
// 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
+ }
193
198
ConstValue :: Indirect { alloc_id, offset } => !tcx
194
199
. global_alloc ( alloc_id)
195
200
. unwrap_memory ( )
@@ -200,7 +205,7 @@ impl<'tcx> ConstValue<'tcx> {
200
205
}
201
206
202
207
/// 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 {
204
209
let ConstValue :: Indirect { alloc_id, .. } = self else {
205
210
return false ;
206
211
} ;
@@ -487,9 +492,8 @@ impl<'tcx> Const<'tcx> {
487
492
/// taking into account even pointer identity tests.
488
493
pub fn is_deterministic ( & self ) -> bool {
489
494
// 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.
493
497
match self {
494
498
Const :: Ty ( _, c) => match c. kind ( ) {
495
499
ty:: ConstKind :: Param ( ..) => true ,
@@ -507,11 +511,11 @@ impl<'tcx> Const<'tcx> {
507
511
| ty:: ConstKind :: Placeholder ( ..) => bug ! ( ) ,
508
512
} ,
509
513
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 ,
513
514
Const :: Val (
514
- ConstValue :: ZeroSized | ConstValue :: Scalar ( _) | ConstValue :: Indirect { .. } ,
515
+ ConstValue :: Slice { .. }
516
+ | ConstValue :: ZeroSized
517
+ | ConstValue :: Scalar ( _)
518
+ | ConstValue :: Indirect { .. } ,
515
519
_,
516
520
) => true ,
517
521
}
0 commit comments