@@ -18,6 +18,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
1818        body :  impl  FnOnce ( & mut  Self )  -> rustc_hir:: Expr < ' hir > , 
1919        contract :  & rustc_ast:: FnContract , 
2020    )  -> rustc_hir:: Expr < ' hir >  { 
21+         // The order in which things are lowered is important! I.e to 
22+         // refer to variables in contract_decls from postcond/precond, 
23+         // we must lower it first! 
24+         let  contract_decls = self . lower_stmts ( & contract. declarations ) . 0 ; 
25+ 
2126        match  ( & contract. requires ,  & contract. ensures )  { 
2227            ( Some ( req) ,  Some ( ens) )  => { 
2328                // Lower the fn contract, which turns: 
@@ -27,6 +32,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
2732                // into: 
2833                // 
2934                // let __postcond = if contract_checks { 
35+                 //     CONTRACT_DECLARATIONS; 
3036                //     contract_check_requires(PRECOND); 
3137                //     Some(|ret_val| POSTCOND) 
3238                // } else { 
@@ -45,8 +51,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
4551                let  precond = self . lower_precond ( req) ; 
4652                let  postcond_checker = self . lower_postcond_checker ( ens) ; 
4753
48-                 let  contract_check =
49-                     self . lower_contract_check_with_postcond ( Some ( precond) ,  postcond_checker) ; 
54+                 let  contract_check = self . lower_contract_check_with_postcond ( 
55+                     contract_decls, 
56+                     Some ( precond) , 
57+                     postcond_checker, 
58+                 ) ; 
5059
5160                let  wrapped_body =
5261                    self . wrap_body_with_contract_check ( body,  contract_check,  postcond_checker. span ) ; 
@@ -68,15 +77,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
6877                //     let ret = { body }; 
6978                // 
7079                //     if contract_checks { 
80+                 //         CONTRACT_DECLARATIONS; 
7181                //         contract_check_ensures(__postcond, ret) 
7282                //     } else { 
7383                //         ret 
7484                //     } 
7585                // } 
76- 
7786                let  postcond_checker = self . lower_postcond_checker ( ens) ; 
7887                let  contract_check =
79-                     self . lower_contract_check_with_postcond ( None ,  postcond_checker) ; 
88+                     self . lower_contract_check_with_postcond ( contract_decls ,   None ,  postcond_checker) ; 
8089
8190                let  wrapped_body =
8291                    self . wrap_body_with_contract_check ( body,  contract_check,  postcond_checker. span ) ; 
@@ -91,12 +100,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
91100                // 
92101                // { 
93102                //      if contracts_checks { 
103+                 //          CONTRACT_DECLARATIONS; 
94104                //          contract_requires(PRECOND); 
95105                //      } 
96106                //      body 
97107                // } 
98108                let  precond = self . lower_precond ( req) ; 
99-                 let  precond_check = self . lower_contract_check_just_precond ( precond) ; 
109+                 let  precond_check = self . lower_contract_check_just_precond ( contract_decls ,   precond) ; 
100110
101111                let  body = self . arena . alloc ( body ( self ) ) ; 
102112
@@ -145,9 +155,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
145155
146156    fn  lower_contract_check_just_precond ( 
147157        & mut  self , 
158+         contract_decls :  & ' hir  [ rustc_hir:: Stmt < ' hir > ] , 
148159        precond :  rustc_hir:: Stmt < ' hir > , 
149160    )  -> rustc_hir:: Stmt < ' hir >  { 
150-         let  stmts = self . arena . alloc_from_iter ( [ precond] . into_iter ( ) ) ; 
161+         let  stmts = self 
162+             . arena 
163+             . alloc_from_iter ( contract_decls. into_iter ( ) . map ( |d| * d) . chain ( [ precond] . into_iter ( ) ) ) ; 
151164
152165        let  then_block_stmts = self . block_all ( precond. span ,  stmts,  None ) ; 
153166        let  then_block = self . arena . alloc ( self . expr_block ( & then_block_stmts) ) ; 
@@ -164,10 +177,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
164177
165178    fn  lower_contract_check_with_postcond ( 
166179        & mut  self , 
180+         contract_decls :  & ' hir  [ rustc_hir:: Stmt < ' hir > ] , 
167181        precond :  Option < rustc_hir:: Stmt < ' hir > > , 
168182        postcond_checker :  & ' hir  rustc_hir:: Expr < ' hir > , 
169183    )  -> & ' hir  rustc_hir:: Expr < ' hir >  { 
170-         let  stmts = self . arena . alloc_from_iter ( precond. into_iter ( ) ) ; 
184+         let  stmts = self 
185+             . arena 
186+             . alloc_from_iter ( contract_decls. into_iter ( ) . map ( |d| * d) . chain ( precond. into_iter ( ) ) ) ; 
171187        let  span = match  precond { 
172188            Some ( precond)  => precond. span , 
173189            None  => postcond_checker. span , 
0 commit comments