@@ -17,10 +17,10 @@ use std::hash::Hash;
1717use std:: collections:: hash_map:: Entry ;
1818
1919use rustc:: hir:: { self , def_id:: DefId } ;
20- use rustc:: mir:: interpret:: ConstEvalErr ;
20+ use rustc:: mir:: interpret:: { Relocations , UndefMask , ConstEvalErr } ;
2121use rustc:: mir;
2222use rustc:: ty:: { self , Ty , TyCtxt , Instance , query:: TyCtxtAt } ;
23- use rustc:: ty:: layout:: { self , Size , LayoutOf , TyLayout } ;
23+ use rustc:: ty:: layout:: { Size , LayoutOf , TyLayout } ;
2424use rustc:: ty:: subst:: Subst ;
2525use rustc_data_structures:: indexed_vec:: IndexVec ;
2626use rustc_data_structures:: fx:: FxHashMap ;
@@ -106,17 +106,43 @@ pub fn mplace_to_const<'tcx>(
106106 let alloc = ecx. memory . get ( ptr. alloc_id ) ?;
107107 assert ! ( alloc. align. abi( ) >= mplace. align. abi( ) ) ;
108108 assert ! ( alloc. bytes. len( ) as u64 - ptr. offset. bytes( ) >= mplace. layout. size. bytes( ) ) ;
109- // FIXME: only clone the parts that interest us (starting at offset, going to offset + size)
110- let mut alloc = alloc. clone ( ) ;
111- // we take `mplace.layout.align` instead of `mplace.align`
112- // as this function is essentially copying the value
113- // out of the larger allocation, so we lose all information about
114- // potential surrounding types with different alignment.
115- alloc. align = mplace. layout . align ;
109+ // FIXME: stop cloning and refer to parts of allocations by giving `ConstValue::ByRef` fields
110+ // for alignment overrides and size of the referred to part
111+ let mut new_alloc = Allocation {
112+ bytes : alloc
113+ . bytes [ ptr. offset . bytes ( ) as usize ..] [ ..mplace. layout . size . bytes ( ) as usize ]
114+ . to_owned ( ) ,
115+ mutability : Mutability :: Immutable ,
116+ relocations : Relocations :: from_presorted ( alloc
117+ . relocations
118+ . iter ( )
119+ . filter_map ( |& ( offset, ( tag, id) ) | if offset < ptr. offset {
120+ None
121+ } else {
122+ Some ( (
123+ offset - ptr. offset ,
124+ ( tag, id)
125+ ) )
126+ } )
127+ . collect ( ) ) ,
128+ undef_mask : UndefMask :: new ( mplace. layout . size ) ,
129+ // we take `mplace.layout.align` instead of `mplace.align`
130+ // as this function is essentially copying the value
131+ // out of the larger allocation, so we lose all information about
132+ // potential surrounding types with different alignment.
133+ align : mplace. layout . align ,
134+ } ;
135+ for i in 0 ..mplace. layout . size . bytes ( ) {
136+ let i = Size :: from_bytes ( i) ;
137+ let j = i + ptr. offset ;
138+ new_alloc. undef_mask . set ( i, alloc. undef_mask . get ( j) ) ;
139+ }
140+
116141 // FIXME shouldnt it be the case that `intern_static` has already
117142 // interned this? I thought that is the entire point of that `FinishStatic` stuff?
118- let alloc = ecx. tcx . intern_const_alloc ( alloc) ;
119- let val = ConstValue :: ByRef ( ptr. alloc_id , alloc, ptr. offset ) ;
143+ let new_alloc = ecx. tcx . intern_const_alloc ( new_alloc) ;
144+ let alloc_id = ecx. tcx . alloc_map . lock ( ) . allocate ( new_alloc) ;
145+ let val = ConstValue :: ByRef ( alloc_id, new_alloc, Size :: ZERO ) ;
120146 Ok ( ty:: Const :: from_const_value ( ecx. tcx . tcx , val, mplace. layout . ty ) )
121147}
122148
0 commit comments