@@ -649,75 +649,83 @@ impl<'b, 'a, 'tcx> MutVisitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
649
649
location : Location ,
650
650
) {
651
651
self . super_terminator ( terminator, location) ;
652
- let source_info = terminator. source_info ; ;
653
- if let TerminatorKind :: Assert { expected, msg, cond, .. } = & terminator. kind {
654
- if let Some ( value) = self . eval_operand ( & cond, source_info) {
655
- trace ! ( "assertion on {:?} should be {:?}" , value, expected) ;
656
- let expected = ScalarMaybeUndef :: from ( Scalar :: from_bool ( * expected) ) ;
657
- if expected != self . ecx . read_scalar ( value) . unwrap ( ) {
658
- // poison all places this operand references so that further code
659
- // doesn't use the invalid value
660
- match cond {
661
- Operand :: Move ( ref place) | Operand :: Copy ( ref place) => {
662
- let mut place = place;
663
- while let Place :: Projection ( ref proj) = * place {
664
- place = & proj. base ;
665
- }
666
- if let Place :: Base ( PlaceBase :: Local ( local) ) = * place {
667
- self . places [ local] = None ;
668
- }
669
- } ,
670
- Operand :: Constant ( _) => { }
652
+ let source_info = terminator. source_info ;
653
+ match & mut terminator. kind {
654
+ TerminatorKind :: Assert { expected, msg, ref mut cond, .. } => {
655
+ if let Some ( value) = self . eval_operand ( & cond, source_info) {
656
+ trace ! ( "assertion on {:?} should be {:?}" , value, expected) ;
657
+ let expected = ScalarMaybeUndef :: from ( Scalar :: from_bool ( * expected) ) ;
658
+ let value_const = self . ecx . read_scalar ( value) . unwrap ( ) ;
659
+ if expected != value_const {
660
+ // poison all places this operand references so that further code
661
+ // doesn't use the invalid value
662
+ match cond {
663
+ Operand :: Move ( ref place) | Operand :: Copy ( ref place) => {
664
+ let mut place = place;
665
+ while let Place :: Projection ( ref proj) = * place {
666
+ place = & proj. base ;
667
+ }
668
+ if let Place :: Base ( PlaceBase :: Local ( local) ) = * place {
669
+ self . places [ local] = None ;
670
+ }
671
+ } ,
672
+ Operand :: Constant ( _) => { }
673
+ }
674
+ let span = terminator. source_info . span ;
675
+ let hir_id = self
676
+ . tcx
677
+ . hir ( )
678
+ . as_local_hir_id ( self . source . def_id ( ) )
679
+ . expect ( "some part of a failing const eval must be local" ) ;
680
+ use rustc:: mir:: interpret:: InterpError :: * ;
681
+ let msg = match msg {
682
+ Overflow ( _) |
683
+ OverflowNeg |
684
+ DivisionByZero |
685
+ RemainderByZero => msg. description ( ) . to_owned ( ) ,
686
+ BoundsCheck { ref len, ref index } => {
687
+ let len = self
688
+ . eval_operand ( len, source_info)
689
+ . expect ( "len must be const" ) ;
690
+ let len = match self . ecx . read_scalar ( len) {
691
+ Ok ( ScalarMaybeUndef :: Scalar ( Scalar :: Bits {
692
+ bits, ..
693
+ } ) ) => bits,
694
+ other => bug ! ( "const len not primitive: {:?}" , other) ,
695
+ } ;
696
+ let index = self
697
+ . eval_operand ( index, source_info)
698
+ . expect ( "index must be const" ) ;
699
+ let index = match self . ecx . read_scalar ( index) {
700
+ Ok ( ScalarMaybeUndef :: Scalar ( Scalar :: Bits {
701
+ bits, ..
702
+ } ) ) => bits,
703
+ other => bug ! ( "const index not primitive: {:?}" , other) ,
704
+ } ;
705
+ format ! (
706
+ "index out of bounds: \
707
+ the len is {} but the index is {}",
708
+ len,
709
+ index,
710
+ )
711
+ } ,
712
+ // Need proper const propagator for these
713
+ _ => return ,
714
+ } ;
715
+ self . tcx . lint_hir (
716
+ :: rustc:: lint:: builtin:: CONST_ERR ,
717
+ hir_id,
718
+ span,
719
+ & msg,
720
+ ) ;
721
+ } else {
722
+ if let ScalarMaybeUndef :: Scalar ( scalar) = value_const {
723
+ * cond = self . operand_from_scalar ( scalar, self . tcx . types . bool ) ;
724
+ }
671
725
}
672
- let span = terminator. source_info . span ;
673
- let hir_id = self
674
- . tcx
675
- . hir ( )
676
- . as_local_hir_id ( self . source . def_id ( ) )
677
- . expect ( "some part of a failing const eval must be local" ) ;
678
- use rustc:: mir:: interpret:: InterpError :: * ;
679
- let msg = match msg {
680
- Overflow ( _) |
681
- OverflowNeg |
682
- DivisionByZero |
683
- RemainderByZero => msg. description ( ) . to_owned ( ) ,
684
- BoundsCheck { ref len, ref index } => {
685
- let len = self
686
- . eval_operand ( len, source_info)
687
- . expect ( "len must be const" ) ;
688
- let len = match self . ecx . read_scalar ( len) {
689
- Ok ( ScalarMaybeUndef :: Scalar ( Scalar :: Bits {
690
- bits, ..
691
- } ) ) => bits,
692
- other => bug ! ( "const len not primitive: {:?}" , other) ,
693
- } ;
694
- let index = self
695
- . eval_operand ( index, source_info)
696
- . expect ( "index must be const" ) ;
697
- let index = match self . ecx . read_scalar ( index) {
698
- Ok ( ScalarMaybeUndef :: Scalar ( Scalar :: Bits {
699
- bits, ..
700
- } ) ) => bits,
701
- other => bug ! ( "const index not primitive: {:?}" , other) ,
702
- } ;
703
- format ! (
704
- "index out of bounds: \
705
- the len is {} but the index is {}",
706
- len,
707
- index,
708
- )
709
- } ,
710
- // Need proper const propagator for these
711
- _ => return ,
712
- } ;
713
- self . tcx . lint_hir (
714
- :: rustc:: lint:: builtin:: CONST_ERR ,
715
- hir_id,
716
- span,
717
- & msg,
718
- ) ;
719
726
}
720
- }
727
+ } ,
728
+ _ => { }
721
729
}
722
730
}
723
731
}
0 commit comments