@@ -6,9 +6,22 @@ use super::FunctionCx;
6
6
use super :: LocalRef ;
7
7
use crate :: traits:: * ;
8
8
9
+ use std:: ops:: ControlFlow ;
10
+
9
11
impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
12
+ /// Lower a single MIR statement, returning [`ControlFlow::Break`] if we must not continue lowering
13
+ /// the rest of the statements in the block.
14
+ ///
15
+ /// Since we are lowering a polymorphic MIR body, we can discover only at this point that we
16
+ /// are lowering `assume(false)`. If we encounter such a statement, there is no reason to lower
17
+ /// the rest of the block; we just emit an unreachable terminator and return
18
+ /// [`ControlFlow::Break`].
10
19
#[ instrument( level = "debug" , skip( self , bx) ) ]
11
- pub fn codegen_statement ( & mut self , bx : & mut Bx , statement : & mir:: Statement < ' tcx > ) {
20
+ pub fn codegen_statement (
21
+ & mut self ,
22
+ bx : & mut Bx ,
23
+ statement : & mir:: Statement < ' tcx > ,
24
+ ) -> ControlFlow < ( ) > {
12
25
self . set_debug_loc ( bx, statement. source_info ) ;
13
26
match statement. kind {
14
27
mir:: StatementKind :: Assign ( box ( ref place, ref rvalue) ) => {
@@ -70,7 +83,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
70
83
mir:: StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: Assume ( ref op) ) => {
71
84
if !matches ! ( bx. tcx( ) . sess. opts. optimize, OptLevel :: No | OptLevel :: Less ) {
72
85
let op_val = self . codegen_operand ( bx, op) ;
73
- bx. assume ( op_val. immediate ( ) ) ;
86
+ let imm = op_val. immediate ( ) ;
87
+ if let Some ( value) = bx. const_to_opt_uint ( imm) {
88
+ // If we are lowering assume(false), just produce an unreachable
89
+ // terminator. We don't emit anything for assume(true).
90
+ if value == 0 {
91
+ bx. unreachable ( ) ;
92
+ return ControlFlow :: Break ( ( ) ) ;
93
+ }
94
+ } else {
95
+ bx. assume ( imm) ;
96
+ }
74
97
}
75
98
}
76
99
mir:: StatementKind :: Intrinsic ( box NonDivergingIntrinsic :: CopyNonOverlapping (
@@ -97,5 +120,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
97
120
| mir:: StatementKind :: PlaceMention ( ..)
98
121
| mir:: StatementKind :: Nop => { }
99
122
}
123
+ ControlFlow :: Continue ( ( ) )
100
124
}
101
125
}
0 commit comments