@@ -90,7 +90,7 @@ pub enum TempState {
9090impl TempState {
9191 pub fn is_promotable ( & self ) -> bool {
9292 debug ! ( "is_promotable: self={:?}" , self ) ;
93- matches ! ( self , TempState :: Defined { .. } )
93+ matches ! ( self , TempState :: Defined { .. } )
9494 }
9595}
9696
@@ -329,7 +329,6 @@ impl<'tcx> Validator<'_, 'tcx> {
329329 return Err ( Unpromotable ) ;
330330 }
331331
332-
333332 Ok ( ( ) )
334333 }
335334 _ => bug ! ( ) ,
@@ -583,18 +582,33 @@ impl<'tcx> Validator<'_, 'tcx> {
583582 }
584583
585584 fn validate_rvalue ( & self , rvalue : & Rvalue < ' tcx > ) -> Result < ( ) , Unpromotable > {
586- match * rvalue {
587- Rvalue :: Cast ( CastKind :: Misc , ref operand, cast_ty) => {
588- let operand_ty = operand. ty ( self . body , self . tcx ) ;
589- let cast_in = CastTy :: from_ty ( operand_ty) . expect ( "bad input type for cast" ) ;
590- let cast_out = CastTy :: from_ty ( cast_ty) . expect ( "bad output type for cast" ) ;
591- if let ( CastTy :: Ptr ( _) | CastTy :: FnPtr , CastTy :: Int ( _) ) = ( cast_in, cast_out) {
592- // ptr-to-int casts are not possible in consts and thus not promotable
593- return Err ( Unpromotable ) ;
585+ match rvalue {
586+ Rvalue :: Use ( operand) | Rvalue :: Repeat ( operand, _) | Rvalue :: UnaryOp ( _, operand) => {
587+ self . validate_operand ( operand) ?;
588+ }
589+
590+ Rvalue :: Discriminant ( place) | Rvalue :: Len ( place) => self . validate_place ( place. as_ref ( ) ) ?,
591+
592+ Rvalue :: ThreadLocalRef ( _) => return Err ( Unpromotable ) ,
593+
594+ Rvalue :: Cast ( kind, operand, cast_ty) => {
595+ if matches ! ( kind, CastKind :: Misc ) {
596+ let operand_ty = operand. ty ( self . body , self . tcx ) ;
597+ let cast_in = CastTy :: from_ty ( operand_ty) . expect ( "bad input type for cast" ) ;
598+ let cast_out = CastTy :: from_ty ( cast_ty) . expect ( "bad output type for cast" ) ;
599+ if let ( CastTy :: Ptr ( _) | CastTy :: FnPtr , CastTy :: Int ( _) ) = ( cast_in, cast_out) {
600+ // ptr-to-int casts are not possible in consts and thus not promotable
601+ return Err ( Unpromotable ) ;
602+ }
603+ // int-to-ptr casts are fine, they just use the integer value at pointer type.
594604 }
605+
606+ self . validate_operand ( operand) ?;
595607 }
596608
597- Rvalue :: BinaryOp ( op, ref lhs, _) => {
609+ Rvalue :: BinaryOp ( op, lhs, rhs)
610+ | Rvalue :: CheckedBinaryOp ( op, lhs, rhs) => {
611+ let op = * op;
598612 if let ty:: RawPtr ( _) | ty:: FnPtr ( ..) = lhs. ty ( self . body , self . tcx ) . kind ( ) {
599613 assert ! (
600614 op == BinOp :: Eq
@@ -609,29 +623,17 @@ impl<'tcx> Validator<'_, 'tcx> {
609623 // raw pointer operations are not allowed inside consts and thus not promotable
610624 return Err ( Unpromotable ) ;
611625 }
612- }
613-
614- Rvalue :: NullaryOp ( NullOp :: Box , _) => return Err ( Unpromotable ) ,
615-
616- // FIXME(RalfJung): the rest is *implicitly considered promotable*... that seems dangerous.
617- _ => { }
618- }
619-
620- match rvalue {
621- Rvalue :: ThreadLocalRef ( _) => Err ( Unpromotable ) ,
622-
623- Rvalue :: NullaryOp ( ..) => Ok ( ( ) ) ,
624626
625- Rvalue :: Discriminant ( place ) | Rvalue :: Len ( place ) => self . validate_place ( place . as_ref ( ) ) ,
627+ // FIXME: reject operations that can fail -- namely, division and modulo.
626628
627- Rvalue :: Use ( operand)
628- | Rvalue :: Repeat ( operand, _)
629- | Rvalue :: UnaryOp ( _, operand)
630- | Rvalue :: Cast ( _, operand, _) => self . validate_operand ( operand) ,
631-
632- Rvalue :: BinaryOp ( _, lhs, rhs) | Rvalue :: CheckedBinaryOp ( _, lhs, rhs) => {
633629 self . validate_operand ( lhs) ?;
634- self . validate_operand ( rhs)
630+ self . validate_operand ( rhs) ?;
631+ }
632+
633+ Rvalue :: NullaryOp ( op, _) => {
634+ if matches ! ( op, NullOp :: Box ) {
635+ return Err ( Unpromotable ) ;
636+ }
635637 }
636638
637639 Rvalue :: AddressOf ( _, place) => {
@@ -646,16 +648,18 @@ impl<'tcx> Validator<'_, 'tcx> {
646648 } ) ;
647649 }
648650 }
649- Err ( Unpromotable )
651+ return Err ( Unpromotable ) ;
650652 }
651653
652654 Rvalue :: Ref ( _, kind, place) => {
653655 // Special-case reborrows to be more like a copy of the reference.
654656 let mut place_simplified = place. as_ref ( ) ;
655657 if let [ proj_base @ .., ProjectionElem :: Deref ] = & place_simplified. projection {
656- let base_ty = Place :: ty_from ( place_simplified. local , proj_base, self . body , self . tcx ) . ty ;
658+ let base_ty =
659+ Place :: ty_from ( place_simplified. local , proj_base, self . body , self . tcx ) . ty ;
657660 if let ty:: Ref ( ..) = base_ty. kind ( ) {
658- place_simplified = PlaceRef { local : place_simplified. local , projection : proj_base } ;
661+ place_simplified =
662+ PlaceRef { local : place_simplified. local , projection : proj_base } ;
659663 }
660664 }
661665
@@ -664,18 +668,16 @@ impl<'tcx> Validator<'_, 'tcx> {
664668 // Check that the reference is fine (using the original place!).
665669 // (Needs to come after `validate_local` to avoid ICEs.)
666670 self . validate_ref ( * kind, place) ?;
667-
668- Ok ( ( ) )
669671 }
670672
671- Rvalue :: Aggregate ( _, ref operands) => {
673+ Rvalue :: Aggregate ( _, operands) => {
672674 for o in operands {
673675 self . validate_operand ( o) ?;
674676 }
675-
676- Ok ( ( ) )
677677 }
678678 }
679+
680+ Ok ( ( ) )
679681 }
680682
681683 fn validate_call (
0 commit comments