11use std:: collections:: { btree_map, VecDeque } ;
22use std:: ptr;
33
4+ use rustc:: hir:: def_id:: DefId ;
45use rustc:: ty:: Instance ;
6+ use rustc:: ty:: ParamEnv ;
57use rustc:: ty:: maps:: TyCtxtAt ;
68use rustc:: ty:: layout:: { self , Align , TargetDataLayout } ;
79use syntax:: ast:: Mutability ;
10+ use rustc:: middle:: const_val:: { ConstVal , ErrKind } ;
811
912use rustc_data_structures:: fx:: { FxHashSet , FxHashMap } ;
1013use rustc:: mir:: interpret:: { MemoryPointer , AllocId , Allocation , AccessKind , Value , Pointer ,
11- EvalResult , PrimVal , EvalErrorKind } ;
14+ EvalResult , PrimVal , EvalErrorKind , GlobalId } ;
1215pub use rustc:: mir:: interpret:: { write_target_uint, write_target_int, read_target_uint} ;
1316
1417use super :: { EvalContext , Machine } ;
@@ -274,6 +277,31 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
274277
275278/// Allocation accessors
276279impl < ' 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+
277305 pub fn get ( & self , id : AllocId ) -> EvalResult < ' tcx , & Allocation > {
278306 // normal alloc?
279307 match self . alloc_map . get ( & id) {
@@ -283,13 +311,19 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'a, 'mir, 'tcx, M> {
283311 Some ( alloc) => Ok ( alloc) ,
284312 None => {
285313 // 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+ } )
293327 } ,
294328 } ,
295329 }
0 commit comments