1+ use rustc_middle:: mir:: interpret:: { alloc_range, AllocRange , ConstValue , Pointer } ;
2+
13use 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+ } ;
38
49#[ derive( Copy , Clone , Debug ) ]
510pub struct Ty ( pub usize ) ;
@@ -105,6 +110,9 @@ pub struct AliasDef(pub(crate) DefId);
105110#[ derive( Clone , PartialEq , Eq , Debug ) ]
106111pub struct TraitDef ( pub ( crate ) DefId ) ;
107112
113+ #[ derive( Clone , PartialEq , Eq , Debug ) ]
114+ pub struct ConstDef ( pub ( crate ) DefId ) ;
115+
108116impl TraitDef {
109117 pub fn trait_decl ( & self ) -> TraitDecl {
110118 with ( |cx| cx. trait_decl ( self ) )
@@ -250,6 +258,7 @@ pub type Bytes = Vec<Option<u8>>;
250258pub type Size = usize ;
251259pub type Prov = Opaque ;
252260pub type Align = u64 ;
261+ pub type Promoted = u32 ;
253262pub type InitMaskMaterialized = Vec < u64 > ;
254263
255264/// Stores the provenance information of pointers stored in memory.
@@ -268,6 +277,142 @@ pub struct Allocation {
268277 pub mutability : Mutability ,
269278}
270279
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+
271416pub enum TraitSpecializationKind {
272417 None ,
273418 Marker ,
0 commit comments