@@ -5,7 +5,7 @@ use crate::hir::{
55} ;
66use crate :: syntax:: ast:: { Block , Callee , DataEffect , Expr , FunctionDecl , Item , LetKind , Stmt } ;
77
8- use super :: local:: { BodyState , merge_if_state, merge_loop_state} ;
8+ use super :: local:: { BodyState , LocalAnalysis , merge_if_state, merge_loop_state} ;
99
1010pub ( crate ) fn check ( analyzer : & mut Analyzer < ' _ > ) {
1111 let functions: Vec < FunctionDecl > = analyzer
@@ -19,19 +19,18 @@ pub(crate) fn check(analyzer: &mut Analyzer<'_>) {
1919 . collect ( ) ;
2020
2121 for function in functions {
22- let mut state = BodyState :: default ( ) ;
23- seed_function_bindings ( analyzer, & function, & mut state) ;
24- check_block ( analyzer, & function, & function. body , & mut state) ;
22+ let local_analysis = LocalAnalysis :: new ( analyzer. hir . function_body ( & function. name ) ) ;
23+ let mut state = local_analysis. initial_state ( ) ;
24+ check_block (
25+ analyzer,
26+ & local_analysis,
27+ & function,
28+ & function. body ,
29+ & mut state,
30+ ) ;
2531 }
2632}
2733
28- fn seed_function_bindings ( analyzer : & Analyzer < ' _ > , function : & FunctionDecl , state : & mut BodyState ) {
29- let Some ( body) = analyzer. hir . function_body ( & function. name ) else {
30- return ;
31- } ;
32- state. seed_params ( & body. bindings ) ;
33- }
34-
3534#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
3635pub ( crate ) enum Flow {
3736 Fallthrough ,
@@ -42,14 +41,15 @@ pub(crate) enum Flow {
4241
4342fn check_block (
4443 analyzer : & mut Analyzer < ' _ > ,
44+ local_analysis : & LocalAnalysis ,
4545 function : & FunctionDecl ,
4646 block : & Block ,
4747 state : & mut BodyState ,
4848) -> Flow {
4949 for statement in & block. statements {
5050 check_moved_uses_in_stmt ( analyzer, statement, state) ;
51- let flow = check_stmt_semantics ( analyzer, function, statement, state) ;
52- apply_stmt_effects ( analyzer, statement, state) ;
51+ let flow = check_stmt_semantics ( analyzer, local_analysis , function, statement, state) ;
52+ apply_stmt_effects ( analyzer, local_analysis , statement, state) ;
5353 if flow != Flow :: Fallthrough {
5454 return flow;
5555 }
@@ -59,6 +59,7 @@ fn check_block(
5959
6060fn check_stmt_semantics (
6161 analyzer : & mut Analyzer < ' _ > ,
62+ local_analysis : & LocalAnalysis ,
6263 function : & FunctionDecl ,
6364 statement : & Stmt ,
6465 state : & mut BodyState ,
@@ -110,19 +111,31 @@ fn check_stmt_semantics(
110111 }
111112 Stmt :: With ( stmt) => {
112113 check_resource_escape ( analyzer, & stmt. binding , & stmt. body ) ;
113- check_block ( analyzer, function, & stmt. body , state)
114+ check_block ( analyzer, local_analysis , function, & stmt. body , state)
114115 }
115116 Stmt :: If ( stmt) => {
116117 check_take_of_handle_field ( analyzer, & stmt. condition , state) ;
117- apply_expr_effects ( analyzer , & stmt. condition , state) ;
118+ apply_expr_effects ( local_analysis , & stmt. condition , state) ;
118119
119120 let base_state = state. clone ( ) ;
120121 let mut then_state = base_state. clone ( ) ;
121- let then_flow = check_block ( analyzer, function, & stmt. then_body , & mut then_state) ;
122+ let then_flow = check_block (
123+ analyzer,
124+ local_analysis,
125+ function,
126+ & stmt. then_body ,
127+ & mut then_state,
128+ ) ;
122129
123130 let else_branch = stmt. else_body . as_ref ( ) . map ( |else_body| {
124131 let mut else_state = base_state. clone ( ) ;
125- let else_flow = check_block ( analyzer, function, else_body, & mut else_state) ;
132+ let else_flow = check_block (
133+ analyzer,
134+ local_analysis,
135+ function,
136+ else_body,
137+ & mut else_state,
138+ ) ;
126139 ( else_state, else_flow)
127140 } ) ;
128141
@@ -131,12 +144,18 @@ fn check_stmt_semantics(
131144 Stmt :: Loop ( stmt) => {
132145 if let Some ( condition) = & stmt. condition {
133146 check_take_of_handle_field ( analyzer, condition, state) ;
134- apply_expr_effects ( analyzer , condition, state) ;
147+ apply_expr_effects ( local_analysis , condition, state) ;
135148 }
136149
137150 let base_state = state. clone ( ) ;
138151 let mut body_state = base_state. clone ( ) ;
139- let body_flow = check_block ( analyzer, function, & stmt. body , & mut body_state) ;
152+ let body_flow = check_block (
153+ analyzer,
154+ local_analysis,
155+ function,
156+ & stmt. body ,
157+ & mut body_state,
158+ ) ;
140159
141160 merge_loop_state (
142161 state,
@@ -156,7 +175,12 @@ fn check_stmt_semantics(
156175 }
157176}
158177
159- fn apply_stmt_effects ( analyzer : & mut Analyzer < ' _ > , statement : & Stmt , state : & mut BodyState ) {
178+ fn apply_stmt_effects (
179+ analyzer : & mut Analyzer < ' _ > ,
180+ local_analysis : & LocalAnalysis ,
181+ statement : & Stmt ,
182+ state : & mut BodyState ,
183+ ) {
160184 match statement {
161185 Stmt :: Let ( stmt) => {
162186 match stmt. kind {
@@ -173,20 +197,20 @@ fn apply_stmt_effects(analyzer: &mut Analyzer<'_>, statement: &Stmt, state: &mut
173197 {
174198 state. record_type ( stmt. name . clone ( ) , type_name) ;
175199 }
176- apply_expr_effects ( analyzer , value, state) ;
200+ apply_expr_effects ( local_analysis , value, state) ;
177201 }
178202 }
179203 Stmt :: Return ( stmt) => {
180204 if let Some ( value) = & stmt. value {
181- apply_expr_effects ( analyzer , value, state) ;
205+ apply_expr_effects ( local_analysis , value, state) ;
182206 }
183207 }
184208 Stmt :: With ( stmt) => {
185- apply_expr_effects ( analyzer , & stmt. resource , state) ;
209+ apply_expr_effects ( local_analysis , & stmt. resource , state) ;
186210 }
187211 Stmt :: If ( _) => { }
188212 Stmt :: Loop ( _) => { }
189- Stmt :: Expr ( expr) => apply_expr_effects ( analyzer , expr, state) ,
213+ Stmt :: Expr ( expr) => apply_expr_effects ( local_analysis , expr, state) ,
190214 Stmt :: Break ( _) | Stmt :: Continue ( _) => { }
191215 Stmt :: Unknown ( _) => { }
192216 }
@@ -199,28 +223,28 @@ fn hir_binding_type(analyzer: &Analyzer<'_>, span: &crate::diagnostic::Span) ->
199223 . and_then ( |binding| binding. type_name . clone ( ) )
200224}
201225
202- fn apply_expr_effects ( analyzer : & mut Analyzer < ' _ > , expr : & Expr , state : & mut BodyState ) {
226+ fn apply_expr_effects ( local_analysis : & LocalAnalysis , expr : & Expr , state : & mut BodyState ) {
203227 match expr {
204228 Expr :: Manage { value, span } => {
205- apply_move_events ( analyzer , span, state) ;
206- apply_expr_effects ( analyzer , value, state) ;
229+ local_analysis . apply_move_events ( span, state) ;
230+ apply_expr_effects ( local_analysis , value, state) ;
207231 }
208232 Expr :: Effect {
209233 effect : DataEffect :: Take ,
210234 value,
211235 span,
212236 } => {
213- apply_move_events ( analyzer , span, state) ;
214- apply_expr_effects ( analyzer , value, state) ;
237+ local_analysis . apply_move_events ( span, state) ;
238+ apply_expr_effects ( local_analysis , value, state) ;
215239 }
216- Expr :: Effect { value, .. } => apply_expr_effects ( analyzer , value, state) ,
240+ Expr :: Effect { value, .. } => apply_expr_effects ( local_analysis , value, state) ,
217241 Expr :: Call { args, span, .. } => {
218- apply_retention_events ( analyzer , span, state) ;
242+ local_analysis . apply_retention_events ( span, state) ;
219243 for arg in args {
220- apply_expr_effects ( analyzer , & arg. value , state) ;
244+ apply_expr_effects ( local_analysis , & arg. value , state) ;
221245 }
222246 }
223- Expr :: Field { base, .. } => apply_expr_effects ( analyzer , base, state) ,
247+ Expr :: Field { base, .. } => apply_expr_effects ( local_analysis , base, state) ,
224248 Expr :: Closure { .. }
225249 | Expr :: Ident ( _, _)
226250 | Expr :: Number ( _, _)
@@ -229,22 +253,6 @@ fn apply_expr_effects(analyzer: &mut Analyzer<'_>, expr: &Expr, state: &mut Body
229253 }
230254}
231255
232- fn apply_move_events (
233- analyzer : & Analyzer < ' _ > ,
234- span : & crate :: diagnostic:: Span ,
235- state : & mut BodyState ,
236- ) {
237- state. apply_move_events ( analyzer. hir . effect_events ( span) ) ;
238- }
239-
240- fn apply_retention_events (
241- analyzer : & Analyzer < ' _ > ,
242- span : & crate :: diagnostic:: Span ,
243- state : & mut BodyState ,
244- ) {
245- state. apply_retention_events ( analyzer. hir . effect_events ( span) ) ;
246- }
247-
248256fn check_moved_uses_in_stmt ( analyzer : & mut Analyzer < ' _ > , statement : & Stmt , state : & BodyState ) {
249257 let mut uses = Vec :: new ( ) ;
250258 collect_stmt_idents ( statement, & mut uses) ;
0 commit comments