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