@@ -90,7 +90,7 @@ pub enum TempState {
90
90
impl TempState {
91
91
pub fn is_promotable ( & self ) -> bool {
92
92
debug ! ( "is_promotable: self={:?}" , self ) ;
93
- matches ! ( self , TempState :: Defined { .. } )
93
+ matches ! ( self , TempState :: Defined { .. } )
94
94
}
95
95
}
96
96
@@ -329,7 +329,6 @@ impl<'tcx> Validator<'_, 'tcx> {
329
329
return Err ( Unpromotable ) ;
330
330
}
331
331
332
-
333
332
Ok ( ( ) )
334
333
}
335
334
_ => bug ! ( ) ,
@@ -583,18 +582,33 @@ impl<'tcx> Validator<'_, 'tcx> {
583
582
}
584
583
585
584
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.
594
604
}
605
+
606
+ self . validate_operand ( operand) ?;
595
607
}
596
608
597
- Rvalue :: BinaryOp ( op, ref lhs, _) => {
609
+ Rvalue :: BinaryOp ( op, lhs, rhs)
610
+ | Rvalue :: CheckedBinaryOp ( op, lhs, rhs) => {
611
+ let op = * op;
598
612
if let ty:: RawPtr ( _) | ty:: FnPtr ( ..) = lhs. ty ( self . body , self . tcx ) . kind ( ) {
599
613
assert ! (
600
614
op == BinOp :: Eq
@@ -609,29 +623,17 @@ impl<'tcx> Validator<'_, 'tcx> {
609
623
// raw pointer operations are not allowed inside consts and thus not promotable
610
624
return Err ( Unpromotable ) ;
611
625
}
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 ( ( ) ) ,
624
626
625
- Rvalue :: Discriminant ( place ) | Rvalue :: Len ( place ) => self . validate_place ( place . as_ref ( ) ) ,
627
+ // FIXME: reject operations that can fail -- namely, division and modulo.
626
628
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) => {
633
629
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
+ }
635
637
}
636
638
637
639
Rvalue :: AddressOf ( _, place) => {
@@ -646,16 +648,18 @@ impl<'tcx> Validator<'_, 'tcx> {
646
648
} ) ;
647
649
}
648
650
}
649
- Err ( Unpromotable )
651
+ return Err ( Unpromotable ) ;
650
652
}
651
653
652
654
Rvalue :: Ref ( _, kind, place) => {
653
655
// Special-case reborrows to be more like a copy of the reference.
654
656
let mut place_simplified = place. as_ref ( ) ;
655
657
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 ;
657
660
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 } ;
659
663
}
660
664
}
661
665
@@ -664,18 +668,16 @@ impl<'tcx> Validator<'_, 'tcx> {
664
668
// Check that the reference is fine (using the original place!).
665
669
// (Needs to come after `validate_local` to avoid ICEs.)
666
670
self . validate_ref ( * kind, place) ?;
667
-
668
- Ok ( ( ) )
669
671
}
670
672
671
- Rvalue :: Aggregate ( _, ref operands) => {
673
+ Rvalue :: Aggregate ( _, operands) => {
672
674
for o in operands {
673
675
self . validate_operand ( o) ?;
674
676
}
675
-
676
- Ok ( ( ) )
677
677
}
678
678
}
679
+
680
+ Ok ( ( ) )
679
681
}
680
682
681
683
fn validate_call (
0 commit comments