@@ -45,9 +45,15 @@ fn mk_eval_cx<'mir, 'tcx>(
45
45
tcx : TyCtxt < ' tcx > ,
46
46
span : Span ,
47
47
param_env : ty:: ParamEnv < ' tcx > ,
48
+ can_access_statics : bool ,
48
49
) -> CompileTimeEvalContext < ' mir , ' tcx > {
49
50
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
+ )
51
57
}
52
58
53
59
fn op_to_const < ' tcx > (
@@ -224,6 +230,12 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
224
230
pub ( super ) loop_detector : snapshot:: InfiniteLoopDetector < ' mir , ' tcx > ,
225
231
}
226
232
233
+ #[ derive( Copy , Clone , Debug ) ]
234
+ pub struct MemoryExtra {
235
+ /// Whether this machine may read from statics
236
+ can_access_statics : bool ,
237
+ }
238
+
227
239
impl < ' mir , ' tcx > CompileTimeInterpreter < ' mir , ' tcx > {
228
240
fn new ( ) -> Self {
229
241
CompileTimeInterpreter {
@@ -311,7 +323,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
311
323
type ExtraFnVal = !;
312
324
313
325
type FrameExtra = ( ) ;
314
- type MemoryExtra = ( ) ;
326
+ type MemoryExtra = MemoryExtra ;
315
327
type AllocExtra = ( ) ;
316
328
317
329
type MemoryMap = FxHashMap < AllocId , ( MemoryKind < !> , Allocation ) > ;
@@ -473,7 +485,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
473
485
474
486
#[ inline( always) ]
475
487
fn init_allocation_extra < ' b > (
476
- _memory_extra : & ( ) ,
488
+ _memory_extra : & MemoryExtra ,
477
489
_id : AllocId ,
478
490
alloc : Cow < ' b , Allocation > ,
479
491
_kind : Option < MemoryKind < !> > ,
@@ -484,7 +496,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
484
496
485
497
#[ inline( always) ]
486
498
fn tag_static_base_pointer (
487
- _memory_extra : & ( ) ,
499
+ _memory_extra : & MemoryExtra ,
488
500
_id : AllocId ,
489
501
) -> Self :: PointerTag {
490
502
( )
@@ -527,6 +539,19 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
527
539
fn stack_push ( _ecx : & mut InterpCx < ' mir , ' tcx , Self > ) -> InterpResult < ' tcx > {
528
540
Ok ( ( ) )
529
541
}
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
+ }
530
555
}
531
556
532
557
/// Extracts a field of a (variant of a) const.
@@ -540,7 +565,7 @@ pub fn const_field<'tcx>(
540
565
value : & ' tcx ty:: Const < ' tcx > ,
541
566
) -> & ' tcx ty:: Const < ' tcx > {
542
567
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 ) ;
544
569
// get the operand again
545
570
let op = ecx. eval_const_to_op ( value, None ) . unwrap ( ) ;
546
571
// downcast
@@ -560,7 +585,7 @@ pub fn const_caller_location<'tcx>(
560
585
( file, line, col) : ( Symbol , u32 , u32 ) ,
561
586
) -> & ' tcx ty:: Const < ' tcx > {
562
587
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 ) ;
564
589
565
590
let loc_ty = tcx. caller_location_ty ( ) ;
566
591
let loc_place = ecx. alloc_caller_location ( file, line, col) ;
@@ -581,7 +606,7 @@ pub fn const_variant_index<'tcx>(
581
606
val : & ' tcx ty:: Const < ' tcx > ,
582
607
) -> VariantIdx {
583
608
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 ) ;
585
610
let op = ecx. eval_const_to_op ( val, None ) . unwrap ( ) ;
586
611
ecx. read_discriminant ( op) . unwrap ( ) . 1
587
612
}
@@ -610,7 +635,9 @@ fn validate_and_turn_into_const<'tcx>(
610
635
key : ty:: ParamEnvAnd < ' tcx , GlobalId < ' tcx > > ,
611
636
) -> :: rustc:: mir:: interpret:: ConstEvalResult < ' tcx > {
612
637
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) ;
614
641
let val = ( || {
615
642
let mplace = ecx. raw_const_to_mplace ( constant) ?;
616
643
let mut ref_tracking = RefTracking :: new ( mplace) ;
@@ -624,8 +651,7 @@ fn validate_and_turn_into_const<'tcx>(
624
651
// Now that we validated, turn this into a proper constant.
625
652
// Statics/promoteds are always `ByRef`, for the rest `op_to_const` decides
626
653
// 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 ( ) {
629
655
let ptr = mplace. ptr . to_ptr ( ) ?;
630
656
Ok ( tcx. mk_const ( ty:: Const {
631
657
val : ty:: ConstKind :: Value ( ConstValue :: ByRef {
@@ -732,12 +758,14 @@ pub fn const_eval_raw_provider<'tcx>(
732
758
return Err ( ErrorHandled :: Reported ) ;
733
759
}
734
760
761
+ let is_static = tcx. is_static ( def_id) ;
762
+
735
763
let span = tcx. def_span ( cid. instance . def_id ( ) ) ;
736
764
let mut ecx = InterpCx :: new (
737
765
tcx. at ( span) ,
738
766
key. param_env ,
739
767
CompileTimeInterpreter :: new ( ) ,
740
- Default :: default ( )
768
+ MemoryExtra { can_access_statics : is_static } ,
741
769
) ;
742
770
743
771
let res = ecx. load_mir ( cid. instance . def , cid. promoted ) ;
@@ -751,7 +779,7 @@ pub fn const_eval_raw_provider<'tcx>(
751
779
} ) . map_err ( |error| {
752
780
let err = error_to_const_error ( & ecx, error) ;
753
781
// errors in statics are always emitted as fatal errors
754
- if tcx . is_static ( def_id ) {
782
+ if is_static {
755
783
// Ensure that if the above error was either `TooGeneric` or `Reported`
756
784
// an error must be reported.
757
785
let v = err. report_as_error ( ecx. tcx , "could not evaluate static initializer" ) ;
0 commit comments