1
+ use rustc_middle:: mir:: interpret:: { alloc_range, AllocRange , 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, 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 ) )
@@ -250,6 +258,7 @@ pub type Bytes = Vec<Option<u8>>;
250
258
pub type Size = usize ;
251
259
pub type Prov = Opaque ;
252
260
pub type Align = u64 ;
261
+ pub type Promoted = u32 ;
253
262
pub type InitMaskMaterialized = Vec < u64 > ;
254
263
255
264
/// Stores the provenance information of pointers stored in memory.
@@ -268,6 +277,142 @@ pub struct Allocation {
268
277
pub mutability : Mutability ,
269
278
}
270
279
280
+ impl Allocation {
281
+ /// Creates new empty `Allocation` from given `Align`.
282
+ fn new_empty_allocation ( align : rustc_target:: abi:: Align ) -> Allocation {
283
+ Allocation {
284
+ bytes : Vec :: new ( ) ,
285
+ provenance : ProvenanceMap { ptrs : Vec :: new ( ) } ,
286
+ align : align. bytes ( ) ,
287
+ mutability : Mutability :: Not ,
288
+ }
289
+ }
290
+ }
291
+
292
+ // We need this method instead of a Stable implementation
293
+ // because we need to get `Ty` of the const we are trying to create, to do that
294
+ // we need to have access to `ConstantKind` but we can't access that inside Stable impl.
295
+ pub fn new_allocation < ' tcx > (
296
+ const_kind : & rustc_middle:: mir:: ConstantKind < ' tcx > ,
297
+ const_value : ConstValue < ' tcx > ,
298
+ tables : & mut Tables < ' tcx > ,
299
+ ) -> Allocation {
300
+ match const_value {
301
+ ConstValue :: Scalar ( scalar) => {
302
+ let size = scalar. size ( ) ;
303
+ let align = tables
304
+ . tcx
305
+ . layout_of ( rustc_middle:: ty:: ParamEnv :: reveal_all ( ) . and ( const_kind. ty ( ) ) )
306
+ . unwrap ( )
307
+ . align ;
308
+ let mut allocation = rustc_middle:: mir:: interpret:: Allocation :: uninit ( size, align. abi ) ;
309
+ allocation
310
+ . write_scalar ( & tables. tcx , alloc_range ( rustc_target:: abi:: Size :: ZERO , size) , scalar)
311
+ . unwrap ( ) ;
312
+ allocation. stable ( tables)
313
+ }
314
+ ConstValue :: ZeroSized => {
315
+ let align = tables
316
+ . tcx
317
+ . layout_of ( rustc_middle:: ty:: ParamEnv :: empty ( ) . and ( const_kind. ty ( ) ) )
318
+ . unwrap ( )
319
+ . align ;
320
+ Allocation :: new_empty_allocation ( align. abi )
321
+ }
322
+ ConstValue :: Slice { data, start, end } => {
323
+ let alloc_id = tables. tcx . create_memory_alloc ( data) ;
324
+ let ptr = Pointer :: new ( alloc_id, rustc_target:: abi:: Size :: from_bytes ( start) ) ;
325
+ let scalar_ptr = rustc_middle:: mir:: interpret:: Scalar :: from_pointer ( ptr, & tables. tcx ) ;
326
+ let scalar_len = rustc_middle:: mir:: interpret:: Scalar :: from_target_usize (
327
+ ( end - start) as u64 ,
328
+ & tables. tcx ,
329
+ ) ;
330
+ let layout = tables
331
+ . tcx
332
+ . layout_of ( rustc_middle:: ty:: ParamEnv :: reveal_all ( ) . and ( const_kind. ty ( ) ) )
333
+ . unwrap ( ) ;
334
+ let mut allocation =
335
+ rustc_middle:: mir:: interpret:: Allocation :: uninit ( layout. size , layout. align . abi ) ;
336
+ allocation
337
+ . write_scalar (
338
+ & tables. tcx ,
339
+ alloc_range ( rustc_target:: abi:: Size :: ZERO , tables. tcx . data_layout . pointer_size ) ,
340
+ scalar_ptr,
341
+ )
342
+ . unwrap ( ) ;
343
+ allocation
344
+ . write_scalar (
345
+ & tables. tcx ,
346
+ alloc_range ( tables. tcx . data_layout . pointer_size , scalar_len. size ( ) ) ,
347
+ scalar_len,
348
+ )
349
+ . unwrap ( ) ;
350
+ allocation. stable ( tables)
351
+ }
352
+ ConstValue :: ByRef { alloc, offset } => {
353
+ let ty_size = tables
354
+ . tcx
355
+ . layout_of ( rustc_middle:: ty:: ParamEnv :: reveal_all ( ) . and ( const_kind. ty ( ) ) )
356
+ . unwrap ( )
357
+ . size ;
358
+ allocation_filter ( & alloc. 0 , alloc_range ( offset, ty_size) , tables)
359
+ }
360
+ }
361
+ }
362
+
363
+ /// Creates an `Allocation` only from information within the `AllocRange`.
364
+ pub fn allocation_filter < ' tcx > (
365
+ alloc : & rustc_middle:: mir:: interpret:: Allocation ,
366
+ alloc_range : AllocRange ,
367
+ tables : & mut Tables < ' tcx > ,
368
+ ) -> Allocation {
369
+ let mut bytes: Vec < Option < u8 > > = alloc
370
+ . inspect_with_uninit_and_ptr_outside_interpreter (
371
+ alloc_range. start . bytes_usize ( ) ..alloc_range. end ( ) . bytes_usize ( ) ,
372
+ )
373
+ . iter ( )
374
+ . copied ( )
375
+ . map ( Some )
376
+ . collect ( ) ;
377
+ for ( i, b) in bytes. iter_mut ( ) . enumerate ( ) {
378
+ if !alloc
379
+ . init_mask ( )
380
+ . get ( rustc_target:: abi:: Size :: from_bytes ( i + alloc_range. start . bytes_usize ( ) ) )
381
+ {
382
+ * b = None ;
383
+ }
384
+ }
385
+ let mut ptrs = Vec :: new ( ) ;
386
+ for ( offset, prov) in alloc
387
+ . provenance ( )
388
+ . ptrs ( )
389
+ . iter ( )
390
+ . filter ( |a| a. 0 >= alloc_range. start && a. 0 <= alloc_range. end ( ) )
391
+ {
392
+ ptrs. push ( ( offset. bytes_usize ( ) - alloc_range. start . bytes_usize ( ) , opaque ( prov) ) ) ;
393
+ }
394
+ Allocation {
395
+ bytes : bytes,
396
+ provenance : ProvenanceMap { ptrs } ,
397
+ align : alloc. align . bytes ( ) ,
398
+ mutability : alloc. mutability . stable ( tables) ,
399
+ }
400
+ }
401
+
402
+ #[ derive( Clone , Debug ) ]
403
+ pub enum ConstantKind {
404
+ Allocated ( Allocation ) ,
405
+ Unevaluated ( UnevaluatedConst ) ,
406
+ }
407
+
408
+ #[ derive( Clone , Debug ) ]
409
+ pub struct UnevaluatedConst {
410
+ pub ty : Ty ,
411
+ pub def : ConstDef ,
412
+ pub args : GenericArgs ,
413
+ pub promoted : Option < Promoted > ,
414
+ }
415
+
271
416
pub enum TraitSpecializationKind {
272
417
None ,
273
418
Marker ,
0 commit comments