@@ -584,6 +584,16 @@ impl<'tcx> Validator<'_, 'tcx> {
584
584
// `validate_rvalue` upon access.
585
585
Operand :: Constant ( c) => {
586
586
if let Some ( def_id) = c. check_static_ptr ( self . tcx ) {
587
+ // Only allow statics (not consts) to refer to other statics.
588
+ // FIXME(eddyb) does this matter at all for promotion?
589
+ // FIXME(RalfJung) it makes little sense to not promote this in `fn/`const fn`,
590
+ // and in `const` this cannot occur anyway. The concern is that we might promote
591
+ // even `let x = &STATIC` which would be useless.
592
+ let is_static = matches ! ( self . const_kind, Some ( hir:: ConstContext :: Static ( _) ) ) ;
593
+ if !is_static {
594
+ return Err ( Unpromotable ) ;
595
+ }
596
+
587
597
let is_thread_local = self . tcx . is_thread_local_static ( def_id) ;
588
598
if is_thread_local {
589
599
return Err ( Unpromotable ) ;
@@ -597,20 +607,20 @@ impl<'tcx> Validator<'_, 'tcx> {
597
607
598
608
fn validate_rvalue ( & self , rvalue : & Rvalue < ' tcx > ) -> Result < ( ) , Unpromotable > {
599
609
match * rvalue {
600
- Rvalue :: Cast ( CastKind :: Misc , ref operand, cast_ty) if self . maybe_runtime ( ) => {
610
+ Rvalue :: Cast ( CastKind :: Misc , ref operand, cast_ty) => {
601
611
let operand_ty = operand. ty ( self . body , self . tcx ) ;
602
612
let cast_in = CastTy :: from_ty ( operand_ty) . expect ( "bad input type for cast" ) ;
603
613
let cast_out = CastTy :: from_ty ( cast_ty) . expect ( "bad output type for cast" ) ;
604
614
match ( cast_in, cast_out) {
605
615
( CastTy :: Ptr ( _) | CastTy :: FnPtr , CastTy :: Int ( _) ) => {
606
- // ptr-to-int casts are not promotable
616
+ // ptr-to-int casts are not possible in consts and thus not promotable
607
617
return Err ( Unpromotable ) ;
608
618
}
609
619
_ => { }
610
620
}
611
621
}
612
622
613
- Rvalue :: BinaryOp ( op, ref lhs, _) if self . maybe_runtime ( ) => {
623
+ Rvalue :: BinaryOp ( op, ref lhs, _) => {
614
624
if let ty:: RawPtr ( _) | ty:: FnPtr ( ..) = lhs. ty ( self . body , self . tcx ) . kind ( ) {
615
625
assert ! (
616
626
op == BinOp :: Eq
@@ -622,7 +632,7 @@ impl<'tcx> Validator<'_, 'tcx> {
622
632
|| op == BinOp :: Offset
623
633
) ;
624
634
625
- // raw pointer operations are not allowed inside promoteds
635
+ // raw pointer operations are not allowed inside consts and thus not promotable
626
636
return Err ( Unpromotable ) ;
627
637
}
628
638
}
0 commit comments