@@ -45,9 +45,15 @@ fn mk_eval_cx<'mir, 'tcx>(
4545 tcx : TyCtxt < ' tcx > ,
4646 span : Span ,
4747 param_env : ty:: ParamEnv < ' tcx > ,
48+ can_access_statics : bool ,
4849) -> CompileTimeEvalContext < ' mir , ' tcx > {
4950 debug ! ( "mk_eval_cx: {:?}" , param_env) ;
50- InterpCx :: new ( tcx. at ( span) , param_env, CompileTimeInterpreter :: new ( ) , Default :: default ( ) )
51+ InterpCx :: new (
52+ tcx. at ( span) ,
53+ param_env,
54+ CompileTimeInterpreter :: new ( ) ,
55+ MemoryExtra { can_access_statics } ,
56+ )
5157}
5258
5359fn op_to_const < ' tcx > (
@@ -224,6 +230,12 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
224230 pub ( super ) loop_detector : snapshot:: InfiniteLoopDetector < ' mir , ' tcx > ,
225231}
226232
233+ #[ derive( Copy , Clone , Debug ) ]
234+ pub struct MemoryExtra {
235+ /// Whether this machine may read from statics
236+ can_access_statics : bool ,
237+ }
238+
227239impl < ' mir , ' tcx > CompileTimeInterpreter < ' mir , ' tcx > {
228240 fn new ( ) -> Self {
229241 CompileTimeInterpreter {
@@ -311,7 +323,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
311323 type ExtraFnVal = !;
312324
313325 type FrameExtra = ( ) ;
314- type MemoryExtra = ( ) ;
326+ type MemoryExtra = MemoryExtra ;
315327 type AllocExtra = ( ) ;
316328
317329 type MemoryMap = FxHashMap < AllocId , ( MemoryKind < !> , Allocation ) > ;
@@ -473,7 +485,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
473485
474486 #[ inline( always) ]
475487 fn init_allocation_extra < ' b > (
476- _memory_extra : & ( ) ,
488+ _memory_extra : & MemoryExtra ,
477489 _id : AllocId ,
478490 alloc : Cow < ' b , Allocation > ,
479491 _kind : Option < MemoryKind < !> > ,
@@ -484,7 +496,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
484496
485497 #[ inline( always) ]
486498 fn tag_static_base_pointer (
487- _memory_extra : & ( ) ,
499+ _memory_extra : & MemoryExtra ,
488500 _id : AllocId ,
489501 ) -> Self :: PointerTag {
490502 ( )
@@ -527,6 +539,19 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
527539 fn stack_push ( _ecx : & mut InterpCx < ' mir , ' tcx , Self > ) -> InterpResult < ' tcx > {
528540 Ok ( ( ) )
529541 }
542+
543+ fn before_access_static (
544+ memory_extra : & MemoryExtra ,
545+ _allocation : & Allocation ,
546+ ) -> InterpResult < ' tcx > {
547+ if memory_extra. can_access_statics {
548+ Ok ( ( ) )
549+ } else {
550+ Err ( ConstEvalError :: NeedsRfc (
551+ "constants accessing static items" . to_string ( ) ,
552+ ) . into ( ) )
553+ }
554+ }
530555}
531556
532557/// Extracts a field of a (variant of a) const.
@@ -540,7 +565,7 @@ pub fn const_field<'tcx>(
540565 value : & ' tcx ty:: Const < ' tcx > ,
541566) -> & ' tcx ty:: Const < ' tcx > {
542567 trace ! ( "const_field: {:?}, {:?}" , field, value) ;
543- let ecx = mk_eval_cx ( tcx, DUMMY_SP , param_env) ;
568+ let ecx = mk_eval_cx ( tcx, DUMMY_SP , param_env, false ) ;
544569 // get the operand again
545570 let op = ecx. eval_const_to_op ( value, None ) . unwrap ( ) ;
546571 // downcast
@@ -560,7 +585,7 @@ pub fn const_caller_location<'tcx>(
560585 ( file, line, col) : ( Symbol , u32 , u32 ) ,
561586) -> & ' tcx ty:: Const < ' tcx > {
562587 trace ! ( "const_caller_location: {}:{}:{}" , file, line, col) ;
563- let mut ecx = mk_eval_cx ( tcx, DUMMY_SP , ty:: ParamEnv :: reveal_all ( ) ) ;
588+ let mut ecx = mk_eval_cx ( tcx, DUMMY_SP , ty:: ParamEnv :: reveal_all ( ) , false ) ;
564589
565590 let loc_ty = tcx. caller_location_ty ( ) ;
566591 let loc_place = ecx. alloc_caller_location ( file, line, col) ;
@@ -581,7 +606,7 @@ pub fn const_variant_index<'tcx>(
581606 val : & ' tcx ty:: Const < ' tcx > ,
582607) -> VariantIdx {
583608 trace ! ( "const_variant_index: {:?}" , val) ;
584- let ecx = mk_eval_cx ( tcx, DUMMY_SP , param_env) ;
609+ let ecx = mk_eval_cx ( tcx, DUMMY_SP , param_env, false ) ;
585610 let op = ecx. eval_const_to_op ( val, None ) . unwrap ( ) ;
586611 ecx. read_discriminant ( op) . unwrap ( ) . 1
587612}
@@ -610,7 +635,9 @@ fn validate_and_turn_into_const<'tcx>(
610635 key : ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ,
611636) -> :: rustc:: mir:: interpret:: ConstEvalResult < ' tcx > {
612637 let cid = key. value ;
613- let ecx = mk_eval_cx ( tcx, tcx. def_span ( key. value . instance . def_id ( ) ) , key. param_env ) ;
638+ let def_id = cid. instance . def . def_id ( ) ;
639+ let is_static = tcx. is_static ( def_id) ;
640+ let ecx = mk_eval_cx ( tcx, tcx. def_span ( key. value . instance . def_id ( ) ) , key. param_env , is_static) ;
614641 let val = ( || {
615642 let mplace = ecx. raw_const_to_mplace ( constant) ?;
616643 let mut ref_tracking = RefTracking :: new ( mplace) ;
@@ -624,8 +651,7 @@ fn validate_and_turn_into_const<'tcx>(
624651 // Now that we validated, turn this into a proper constant.
625652 // Statics/promoteds are always `ByRef`, for the rest `op_to_const` decides
626653 // whether they become immediates.
627- let def_id = cid. instance . def . def_id ( ) ;
628- if tcx. is_static ( def_id) || cid. promoted . is_some ( ) {
654+ if is_static || cid. promoted . is_some ( ) {
629655 let ptr = mplace. ptr . to_ptr ( ) ?;
630656 Ok ( tcx. mk_const ( ty:: Const {
631657 val : ty:: ConstKind :: Value ( ConstValue :: ByRef {
@@ -732,12 +758,14 @@ pub fn const_eval_raw_provider<'tcx>(
732758 return Err ( ErrorHandled :: Reported ) ;
733759 }
734760
761+ let is_static = tcx. is_static ( def_id) ;
762+
735763 let span = tcx. def_span ( cid. instance . def_id ( ) ) ;
736764 let mut ecx = InterpCx :: new (
737765 tcx. at ( span) ,
738766 key. param_env ,
739767 CompileTimeInterpreter :: new ( ) ,
740- Default :: default ( )
768+ MemoryExtra { can_access_statics : is_static } ,
741769 ) ;
742770
743771 let res = ecx. load_mir ( cid. instance . def , cid. promoted ) ;
@@ -751,7 +779,7 @@ pub fn const_eval_raw_provider<'tcx>(
751779 } ) . map_err ( |error| {
752780 let err = error_to_const_error ( & ecx, error) ;
753781 // errors in statics are always emitted as fatal errors
754- if tcx . is_static ( def_id ) {
782+ if is_static {
755783 // Ensure that if the above error was either `TooGeneric` or `Reported`
756784 // an error must be reported.
757785 let v = err. report_as_error ( ecx. tcx , "could not evaluate static initializer" ) ;
0 commit comments