@@ -584,6 +584,16 @@ impl<'tcx> Validator<'_, 'tcx> {
584584 // `validate_rvalue` upon access.
585585 Operand :: Constant ( c) => {
586586 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+
587597 let is_thread_local = self . tcx . is_thread_local_static ( def_id) ;
588598 if is_thread_local {
589599 return Err ( Unpromotable ) ;
@@ -597,20 +607,20 @@ impl<'tcx> Validator<'_, 'tcx> {
597607
598608 fn validate_rvalue ( & self , rvalue : & Rvalue < ' tcx > ) -> Result < ( ) , Unpromotable > {
599609 match * rvalue {
600- Rvalue :: Cast ( CastKind :: Misc , ref operand, cast_ty) if self . maybe_runtime ( ) => {
610+ Rvalue :: Cast ( CastKind :: Misc , ref operand, cast_ty) => {
601611 let operand_ty = operand. ty ( self . body , self . tcx ) ;
602612 let cast_in = CastTy :: from_ty ( operand_ty) . expect ( "bad input type for cast" ) ;
603613 let cast_out = CastTy :: from_ty ( cast_ty) . expect ( "bad output type for cast" ) ;
604614 match ( cast_in, cast_out) {
605615 ( 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
607617 return Err ( Unpromotable ) ;
608618 }
609619 _ => { }
610620 }
611621 }
612622
613- Rvalue :: BinaryOp ( op, ref lhs, _) if self . maybe_runtime ( ) => {
623+ Rvalue :: BinaryOp ( op, ref lhs, _) => {
614624 if let ty:: RawPtr ( _) | ty:: FnPtr ( ..) = lhs. ty ( self . body , self . tcx ) . kind ( ) {
615625 assert ! (
616626 op == BinOp :: Eq
@@ -622,7 +632,7 @@ impl<'tcx> Validator<'_, 'tcx> {
622632 || op == BinOp :: Offset
623633 ) ;
624634
625- // raw pointer operations are not allowed inside promoteds
635+ // raw pointer operations are not allowed inside consts and thus not promotable
626636 return Err ( Unpromotable ) ;
627637 }
628638 }
0 commit comments