1
+ use rustc_middle:: mir:: interpret:: { alloc_range, ConstValue , Pointer } ;
2
+
1
3
use super :: { mir:: Mutability , mir:: Safety , with, DefId } ;
2
- use crate :: rustc_internal:: Opaque ;
4
+ use crate :: {
5
+ rustc_internal:: Opaque ,
6
+ rustc_smir:: { Stable , Tables } ,
7
+ } ;
3
8
4
9
#[ derive( Copy , Clone , Debug ) ]
5
10
pub struct Ty ( pub usize ) ;
@@ -105,6 +110,9 @@ pub struct AliasDef(pub(crate) DefId);
105
110
#[ derive( Clone , PartialEq , Eq , Debug ) ]
106
111
pub struct TraitDef ( pub ( crate ) DefId ) ;
107
112
113
+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
114
+ pub struct ConstDef ( pub ( crate ) DefId ) ;
115
+
108
116
impl TraitDef {
109
117
pub fn trait_decl ( & self ) -> TraitDecl {
110
118
with ( |cx| cx. trait_decl ( self ) )
@@ -248,6 +256,7 @@ pub type Bytes = Vec<Option<u8>>;
248
256
pub type Size = usize ;
249
257
pub type Prov = Opaque ;
250
258
pub type Align = u64 ;
259
+ pub type Promoted = u32 ;
251
260
pub type InitMaskMaterialized = Vec < u64 > ;
252
261
253
262
/// Stores the provenance information of pointers stored in memory.
@@ -266,6 +275,109 @@ pub struct Allocation {
266
275
pub mutability : Mutability ,
267
276
}
268
277
278
+ impl Allocation {
279
+ /// Creates new empty `Allocation` from given `Align`.
280
+ fn new_empty_allocation ( align : rustc_target:: abi:: Align ) -> Allocation {
281
+ Allocation {
282
+ bytes : Vec :: new ( ) ,
283
+ provenance : ProvenanceMap { ptrs : Vec :: new ( ) } ,
284
+ align : align. bytes ( ) ,
285
+ mutability : Mutability :: Not ,
286
+ }
287
+ }
288
+ }
289
+
290
+ // We need this method instead of a Stable implementation
291
+ // because we need to get `Ty` of the const we are trying to create, to do that
292
+ // we need to have access to `ConstantKind` but we can't access that inside Stable impl.
293
+ pub fn new_allocation < ' tcx > (
294
+ const_kind : & rustc_middle:: mir:: ConstantKind < ' tcx > ,
295
+ const_value : ConstValue < ' tcx > ,
296
+ tables : & mut Tables < ' tcx > ,
297
+ ) -> Allocation {
298
+ match const_value {
299
+ ConstValue :: Scalar ( scalar) => {
300
+ let size = scalar. size ( ) ;
301
+ let align = tables
302
+ . tcx
303
+ . layout_of ( rustc_middle:: ty:: ParamEnv :: reveal_all ( ) . and ( const_kind. ty ( ) ) )
304
+ . unwrap ( )
305
+ . align ;
306
+ let mut allocation = rustc_middle:: mir:: interpret:: Allocation :: uninit ( size, align. abi ) ;
307
+ allocation
308
+ . write_scalar ( & tables. tcx , alloc_range ( rustc_target:: abi:: Size :: ZERO , size) , scalar)
309
+ . unwrap ( ) ;
310
+ allocation. stable ( tables)
311
+ }
312
+ ConstValue :: ZeroSized => {
313
+ let align = tables
314
+ . tcx
315
+ . layout_of ( rustc_middle:: ty:: ParamEnv :: empty ( ) . and ( const_kind. ty ( ) ) )
316
+ . unwrap ( )
317
+ . align ;
318
+ Allocation :: new_empty_allocation ( align. abi )
319
+ }
320
+ ConstValue :: Slice { data, start, end } => {
321
+ let alloc_id = tables. tcx . create_memory_alloc ( data) ;
322
+ let ptr = Pointer :: new ( alloc_id, rustc_target:: abi:: Size :: from_bytes ( start) ) ;
323
+ let scalar_ptr = rustc_middle:: mir:: interpret:: Scalar :: from_pointer ( ptr, & tables. tcx ) ;
324
+ let scalar_len = rustc_middle:: mir:: interpret:: Scalar :: from_target_usize (
325
+ ( end - start) as u64 ,
326
+ & tables. tcx ,
327
+ ) ;
328
+ let layout = tables
329
+ . tcx
330
+ . layout_of ( rustc_middle:: ty:: ParamEnv :: reveal_all ( ) . and ( const_kind. ty ( ) ) )
331
+ . unwrap ( ) ;
332
+ let mut allocation =
333
+ rustc_middle:: mir:: interpret:: Allocation :: uninit ( layout. size , layout. align . abi ) ;
334
+ allocation
335
+ . write_scalar (
336
+ & tables. tcx ,
337
+ alloc_range ( rustc_target:: abi:: Size :: ZERO , tables. tcx . data_layout . pointer_size ) ,
338
+ scalar_ptr,
339
+ )
340
+ . unwrap ( ) ;
341
+ allocation
342
+ . write_scalar (
343
+ & tables. tcx ,
344
+ alloc_range ( tables. tcx . data_layout . pointer_size , scalar_len. size ( ) ) ,
345
+ scalar_len,
346
+ )
347
+ . unwrap ( ) ;
348
+ allocation. stable ( tables)
349
+ }
350
+ ConstValue :: ByRef { alloc, offset } => {
351
+ let ty_size = tables
352
+ . tcx
353
+ . layout_of ( rustc_middle:: ty:: ParamEnv :: reveal_all ( ) . and ( const_kind. ty ( ) ) )
354
+ . unwrap ( )
355
+ . size ;
356
+ let bytes = alloc. 0 . get_bytes_unchecked ( alloc_range ( offset, ty_size) ) ;
357
+ let offset_allocation = rustc_middle:: mir:: interpret:: Allocation :: from_bytes (
358
+ bytes,
359
+ alloc. 0 . align ,
360
+ alloc. 0 . mutability ,
361
+ ) ;
362
+ offset_allocation. stable ( tables)
363
+ }
364
+ }
365
+ }
366
+
367
+ #[ derive( Clone , Debug ) ]
368
+ pub enum ConstantKind {
369
+ Allocated ( Allocation ) ,
370
+ Unevaluated ( UnevaluatedConst ) ,
371
+ }
372
+
373
+ #[ derive( Clone , Debug ) ]
374
+ pub struct UnevaluatedConst {
375
+ pub ty : Ty ,
376
+ pub def : ConstDef ,
377
+ pub args : GenericArgs ,
378
+ pub promoted : Option < Promoted > ,
379
+ }
380
+
269
381
pub enum TraitSpecializationKind {
270
382
None ,
271
383
Marker ,
0 commit comments