@@ -17,10 +17,10 @@ use std::hash::Hash;
17
17
use std:: collections:: hash_map:: Entry ;
18
18
19
19
use rustc:: hir:: { self , def_id:: DefId } ;
20
- use rustc:: mir:: interpret:: ConstEvalErr ;
20
+ use rustc:: mir:: interpret:: { Relocations , UndefMask , ConstEvalErr } ;
21
21
use rustc:: mir;
22
22
use 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 } ;
24
24
use rustc:: ty:: subst:: Subst ;
25
25
use rustc_data_structures:: indexed_vec:: IndexVec ;
26
26
use rustc_data_structures:: fx:: FxHashMap ;
@@ -106,17 +106,43 @@ pub fn mplace_to_const<'tcx>(
106
106
let alloc = ecx. memory . get ( ptr. alloc_id ) ?;
107
107
assert ! ( alloc. align. abi( ) >= mplace. align. abi( ) ) ;
108
108
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
+
116
141
// FIXME shouldnt it be the case that `intern_static` has already
117
142
// 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 ) ;
120
146
Ok ( ty:: Const :: from_const_value ( ecx. tcx . tcx , val, mplace. layout . ty ) )
121
147
}
122
148
0 commit comments