1
1
use std:: collections:: { btree_map, VecDeque } ;
2
2
use std:: ptr;
3
3
4
+ use rustc:: hir:: def_id:: DefId ;
4
5
use rustc:: ty:: Instance ;
6
+ use rustc:: ty:: ParamEnv ;
5
7
use rustc:: ty:: maps:: TyCtxtAt ;
6
8
use rustc:: ty:: layout:: { self , Align , TargetDataLayout } ;
7
9
use syntax:: ast:: Mutability ;
10
+ use rustc:: middle:: const_val:: { ConstVal , ErrKind } ;
8
11
9
12
use rustc_data_structures:: fx:: { FxHashSet , FxHashMap } ;
10
13
use rustc:: mir:: interpret:: { MemoryPointer , AllocId , Allocation , AccessKind , Value , Pointer ,
11
- EvalResult , PrimVal , EvalErrorKind } ;
14
+ EvalResult , PrimVal , EvalErrorKind , GlobalId } ;
12
15
pub use rustc:: mir:: interpret:: { write_target_uint, write_target_int, read_target_uint} ;
13
16
14
17
use super :: { EvalContext , Machine } ;
@@ -274,6 +277,31 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
274
277
275
278
/// Allocation accessors
276
279
impl < ' a , ' mir , ' tcx , M : Machine < ' mir , ' tcx > > Memory < ' a , ' mir , ' tcx , M > {
280
+ fn const_eval_static ( & self , def_id : DefId ) -> EvalResult < ' tcx , & ' tcx Allocation > {
281
+ let instance = Instance :: mono ( self . tcx . tcx , def_id) ;
282
+ let gid = GlobalId {
283
+ instance,
284
+ promoted : None ,
285
+ } ;
286
+ self . tcx . const_eval ( ParamEnv :: reveal_all ( ) . and ( gid) ) . map_err ( |err| {
287
+ match * err. kind {
288
+ ErrKind :: Miri ( ref err, _) => match err. kind {
289
+ EvalErrorKind :: TypeckError |
290
+ EvalErrorKind :: Layout ( _) => EvalErrorKind :: TypeckError . into ( ) ,
291
+ _ => EvalErrorKind :: ReferencedConstant . into ( ) ,
292
+ } ,
293
+ ErrKind :: TypeckError => EvalErrorKind :: TypeckError . into ( ) ,
294
+ ref other => bug ! ( "const eval returned {:?}" , other) ,
295
+ }
296
+ } ) . map ( |val| {
297
+ let const_val = match val. val {
298
+ ConstVal :: Value ( val) => val,
299
+ ConstVal :: Unevaluated ( ..) => bug ! ( "should be evaluated" ) ,
300
+ } ;
301
+ self . tcx . const_value_to_allocation ( ( const_val, val. ty ) )
302
+ } )
303
+ }
304
+
277
305
pub fn get ( & self , id : AllocId ) -> EvalResult < ' tcx , & Allocation > {
278
306
// normal alloc?
279
307
match self . alloc_map . get ( & id) {
@@ -283,13 +311,19 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
283
311
Some ( alloc) => Ok ( alloc) ,
284
312
None => {
285
313
// static alloc?
286
- self . tcx . interpret_interner . get_alloc ( id)
287
- // no alloc? produce an error
288
- . ok_or_else ( || if self . tcx . interpret_interner . get_fn ( id) . is_some ( ) {
289
- EvalErrorKind :: DerefFunctionPointer . into ( )
290
- } else {
291
- EvalErrorKind :: DanglingPointerDeref . into ( )
292
- } )
314
+ if let Some ( a) = self . tcx . interpret_interner . get_alloc ( id) {
315
+ return Ok ( a) ;
316
+ }
317
+ // static variable?
318
+ if let Some ( did) = self . tcx . interpret_interner . get_static ( id) {
319
+ return self . const_eval_static ( did) ;
320
+ }
321
+ // otherwise return an error
322
+ Err ( if self . tcx . interpret_interner . get_fn ( id) . is_some ( ) {
323
+ EvalErrorKind :: DerefFunctionPointer . into ( )
324
+ } else {
325
+ EvalErrorKind :: DanglingPointerDeref . into ( )
326
+ } )
293
327
} ,
294
328
} ,
295
329
}
0 commit comments