11use crate :: analyzer:: Analyzer ;
22use crate :: diagnostic:: { Diagnostic , code} ;
3- use crate :: hir:: {
4- CallResolution , HirEffectEventKind , HirReturnProof , HirTypeKind , ResolvedCalleeKind ,
5- } ;
3+ use crate :: hir:: { CallResolution , HirReturnProof , HirTypeKind , ResolvedCalleeKind } ;
64use crate :: syntax:: ast:: { Block , Callee , DataEffect , Expr , FunctionDecl , Item , LetKind , Stmt } ;
75
86use super :: local:: { BodyState , LocalAnalysis , merge_if_state, merge_loop_state} ;
@@ -110,7 +108,7 @@ fn check_stmt_semantics(
110108 Flow :: Return
111109 }
112110 Stmt :: With ( stmt) => {
113- check_resource_escape ( analyzer, & stmt. binding , & stmt. body ) ;
111+ check_resource_escape ( analyzer, local_analysis , & stmt. binding , & stmt. body ) ;
114112 check_block ( analyzer, local_analysis, function, & stmt. body , state)
115113 }
116114 Stmt :: If ( stmt) => {
@@ -383,7 +381,12 @@ fn check_take_of_handle_in_stmt(analyzer: &mut Analyzer<'_>, statement: &Stmt, s
383381 }
384382}
385383
386- fn check_resource_escape ( analyzer : & mut Analyzer < ' _ > , binding : & str , body : & Block ) {
384+ fn check_resource_escape (
385+ analyzer : & mut Analyzer < ' _ > ,
386+ local_analysis : & LocalAnalysis ,
387+ binding : & str ,
388+ body : & Block ,
389+ ) {
387390 for statement in & body. statements {
388391 match statement {
389392 Stmt :: Return ( stmt) => {
@@ -393,7 +396,7 @@ fn check_resource_escape(analyzer: &mut Analyzer<'_>, binding: &str, body: &Bloc
393396 resource_escape_diagnostic ( analyzer, binding, span. clone ( ) ) ;
394397 }
395398 if let Some ( value) = & stmt. value {
396- check_resource_escape_expr ( analyzer, binding, value) ;
399+ check_resource_escape_expr ( analyzer, local_analysis , binding, value) ;
397400 }
398401 }
399402 Stmt :: Let ( stmt) => {
@@ -404,73 +407,73 @@ fn check_resource_escape(analyzer: &mut Analyzer<'_>, binding: &str, body: &Bloc
404407 resource_capture_diagnostic ( analyzer, binding, span. clone ( ) ) ;
405408 }
406409 if let Some ( value) = & stmt. value {
407- check_resource_escape_expr ( analyzer, binding, value) ;
410+ check_resource_escape_expr ( analyzer, local_analysis , binding, value) ;
408411 }
409412 }
410- Stmt :: Expr ( expr) => check_resource_escape_expr ( analyzer, binding, expr) ,
411- Stmt :: With ( stmt) => check_resource_escape ( analyzer, binding, & stmt. body ) ,
413+ Stmt :: Expr ( expr) => check_resource_escape_expr ( analyzer, local_analysis, binding, expr) ,
414+ Stmt :: With ( stmt) => {
415+ check_resource_escape ( analyzer, local_analysis, binding, & stmt. body )
416+ }
412417 Stmt :: If ( stmt) => {
413- check_resource_escape_expr ( analyzer, binding, & stmt. condition ) ;
414- check_resource_escape ( analyzer, binding, & stmt. then_body ) ;
418+ check_resource_escape_expr ( analyzer, local_analysis , binding, & stmt. condition ) ;
419+ check_resource_escape ( analyzer, local_analysis , binding, & stmt. then_body ) ;
415420 if let Some ( else_body) = & stmt. else_body {
416- check_resource_escape ( analyzer, binding, else_body) ;
421+ check_resource_escape ( analyzer, local_analysis , binding, else_body) ;
417422 }
418423 }
419424 Stmt :: Loop ( stmt) => {
420425 if let Some ( condition) = & stmt. condition {
421- check_resource_escape_expr ( analyzer, binding, condition) ;
426+ check_resource_escape_expr ( analyzer, local_analysis , binding, condition) ;
422427 }
423- check_resource_escape ( analyzer, binding, & stmt. body ) ;
428+ check_resource_escape ( analyzer, local_analysis , binding, & stmt. body ) ;
424429 }
425430 Stmt :: Break ( _) | Stmt :: Continue ( _) => { }
426431 Stmt :: Unknown ( _) => { }
427432 }
428433 }
429434}
430435
431- fn check_resource_escape_expr ( analyzer : & mut Analyzer < ' _ > , binding : & str , expr : & Expr ) {
436+ fn check_resource_escape_expr (
437+ analyzer : & mut Analyzer < ' _ > ,
438+ local_analysis : & LocalAnalysis ,
439+ binding : & str ,
440+ expr : & Expr ,
441+ ) {
432442 match expr {
433443 Expr :: Manage { value, span } => {
434444 if let Expr :: Ident ( name, _) = value. as_ref ( )
435445 && name == binding
436446 {
437447 resource_escape_diagnostic ( analyzer, binding, span. clone ( ) ) ;
438448 }
439- check_resource_escape_expr ( analyzer, binding, value) ;
449+ check_resource_escape_expr ( analyzer, local_analysis, binding, value) ;
450+ }
451+ Expr :: Effect { value, .. } => {
452+ check_resource_escape_expr ( analyzer, local_analysis, binding, value) ;
440453 }
441- Expr :: Effect { value, .. } => check_resource_escape_expr ( analyzer, binding, value) ,
442454 Expr :: Call { args, span, .. } => {
443- check_resource_retained_by_call ( analyzer, binding, span) ;
455+ check_resource_retained_by_call ( analyzer, local_analysis , binding, span) ;
444456 for arg in args {
445- check_resource_escape_expr ( analyzer, binding, & arg. value ) ;
457+ check_resource_escape_expr ( analyzer, local_analysis , binding, & arg. value ) ;
446458 }
447459 }
448- Expr :: Field { base, .. } => check_resource_escape_expr ( analyzer, binding, base) ,
449- Expr :: Closure { body, .. } => check_resource_escape ( analyzer, binding, body) ,
460+ Expr :: Field { base, .. } => {
461+ check_resource_escape_expr ( analyzer, local_analysis, binding, base) ;
462+ }
463+ Expr :: Closure { body, .. } => {
464+ check_resource_escape ( analyzer, local_analysis, binding, body)
465+ }
450466 Expr :: Ident ( _, _) | Expr :: Number ( _, _) | Expr :: String ( _, _) | Expr :: Unknown ( _) => { }
451467 }
452468}
453469
454470fn check_resource_retained_by_call (
455471 analyzer : & mut Analyzer < ' _ > ,
472+ local_analysis : & LocalAnalysis ,
456473 binding : & str ,
457474 span : & crate :: diagnostic:: Span ,
458475) {
459- let escaping_spans: Vec < crate :: diagnostic:: Span > = analyzer
460- . hir
461- . effect_events ( span)
462- . iter ( )
463- . filter_map ( |event| {
464- if matches ! ( event. kind, HirEffectEventKind :: Retain { .. } )
465- && event. binding_name == binding
466- {
467- Some ( event. value_span . clone ( ) )
468- } else {
469- None
470- }
471- } )
472- . collect ( ) ;
473- for escaping_span in escaping_spans {
476+ for escaping_span in local_analysis. retained_value_spans ( span, binding) {
474477 resource_escape_diagnostic ( analyzer, binding, escaping_span) ;
475478 }
476479}
0 commit comments