@@ -2,6 +2,7 @@ use std::collections::{HashMap, HashSet};
22
33use crate :: analyzer:: Analyzer ;
44use crate :: diagnostic:: { Diagnostic , code} ;
5+ use crate :: hir:: { CallResolution , HirTypeKind , ResolvedCalleeKind } ;
56use crate :: syntax:: ast:: {
67 Block , CallArg , Callee , DataEffect , Expr , FunctionDecl , Item , LetKind , Stmt ,
78} ;
@@ -342,8 +343,10 @@ fn apply_expr_effects(analyzer: &mut Analyzer<'_>, expr: &Expr, state: &mut Body
342343 apply_expr_effects ( analyzer, value, state) ;
343344 }
344345 Expr :: Effect { value, .. } => apply_expr_effects ( analyzer, value, state) ,
345- Expr :: Call { callee, args, .. } => {
346- apply_retention_effects ( analyzer, callee, args, state) ;
346+ Expr :: Call {
347+ callee, args, span, ..
348+ } => {
349+ apply_retention_effects ( analyzer, callee, span, args, state) ;
347350 for arg in args {
348351 apply_expr_effects ( analyzer, & arg. value , state) ;
349352 }
@@ -360,21 +363,23 @@ fn apply_expr_effects(analyzer: &mut Analyzer<'_>, expr: &Expr, state: &mut Body
360363fn apply_retention_effects (
361364 analyzer : & Analyzer < ' _ > ,
362365 callee : & Callee ,
366+ span : & crate :: diagnostic:: Span ,
363367 args : & [ CallArg ] ,
364368 state : & mut BodyState ,
365369) {
366- let Some ( signature) = analyzer. resolve_callee ( callee) else {
367- return ;
370+ let retained_params = match analyzer. resolve_call_site ( callee, span) {
371+ CallResolution :: Resolved { signature, .. } => signature. retained_params ,
372+ CallResolution :: EnumVariant | CallResolution :: Unknown => return ,
368373 } ;
369- if signature . retained_params . is_empty ( ) {
374+ if retained_params. is_empty ( ) {
370375 return ;
371376 }
372377
373378 for arg in args {
374379 let Some ( name) = & arg. name else {
375380 continue ;
376381 } ;
377- if !signature . retained_params . contains ( name) {
382+ if !retained_params. contains ( name) {
378383 continue ;
379384 }
380385 if let Expr :: Effect {
@@ -577,8 +582,10 @@ fn check_resource_escape_expr(analyzer: &mut Analyzer<'_>, binding: &str, expr:
577582 check_resource_escape_expr ( analyzer, binding, value) ;
578583 }
579584 Expr :: Effect { value, .. } => check_resource_escape_expr ( analyzer, binding, value) ,
580- Expr :: Call { callee, args, .. } => {
581- check_resource_retained_by_call ( analyzer, binding, callee, args) ;
585+ Expr :: Call {
586+ callee, args, span, ..
587+ } => {
588+ check_resource_retained_by_call ( analyzer, binding, callee, span, args) ;
582589 for arg in args {
583590 check_resource_escape_expr ( analyzer, binding, & arg. value ) ;
584591 }
@@ -593,15 +600,16 @@ fn check_resource_retained_by_call(
593600 analyzer : & mut Analyzer < ' _ > ,
594601 binding : & str ,
595602 callee : & Callee ,
603+ span : & crate :: diagnostic:: Span ,
596604 args : & [ CallArg ] ,
597605) {
598- let Some ( signature) = analyzer. resolve_callee ( callee) else {
599- return ;
606+ let retained_params = match analyzer. resolve_call_site ( callee, span) {
607+ CallResolution :: Resolved { signature, .. } => signature. retained_params ,
608+ CallResolution :: EnumVariant | CallResolution :: Unknown => return ,
600609 } ;
601- if signature . retained_params . is_empty ( ) {
610+ if retained_params. is_empty ( ) {
602611 return ;
603612 }
604- let retained_params = signature. retained_params . clone ( ) ;
605613
606614 for arg in args {
607615 let Some ( name) = & arg. name else {
@@ -702,13 +710,20 @@ fn check_fresh_return(
702710 ) ;
703711 }
704712 Expr :: Call { callee, span, .. } => {
705- let constructor_is_struct = match callee {
706- Callee :: Name ( name) => is_struct_type ( analyzer, name) ,
707- Callee :: Qualified { .. } => false ,
713+ let resolution = analyzer. resolve_call_site ( callee, span) ;
714+ let constructor_is_struct = matches ! (
715+ resolution,
716+ CallResolution :: Resolved {
717+ kind: ResolvedCalleeKind :: Constructor {
718+ type_kind: HirTypeKind :: Struct
719+ } ,
720+ ..
721+ }
722+ ) ;
723+ let call_returns_fresh = match resolution {
724+ CallResolution :: Resolved { signature, .. } => signature. returns_fresh ,
725+ CallResolution :: EnumVariant | CallResolution :: Unknown => false ,
708726 } ;
709- let call_returns_fresh = analyzer
710- . resolve_callee ( callee)
711- . is_some_and ( |signature| signature. returns_fresh ) ;
712727 if !constructor_is_struct && !call_returns_fresh {
713728 analyzer. diagnostics . push (
714729 Diagnostic :: warning (
@@ -781,7 +796,7 @@ fn infer_expr_type(analyzer: &Analyzer<'_>, expr: &Expr, state: &BodyState) -> O
781796 Expr :: Effect { value, .. } | Expr :: Manage { value, .. } => {
782797 infer_expr_type ( analyzer, value, state)
783798 }
784- Expr :: Call { callee, .. } => infer_call_type ( analyzer, callee) ,
799+ Expr :: Call { callee, span , .. } => infer_call_type ( analyzer, callee, span ) ,
785800 Expr :: Field { base, name, .. } => {
786801 let base_type = infer_expr_type ( analyzer, base, state) ?;
787802 let field = analyzer. hir . type_info ( & base_type) ?. fields . get ( name) ?;
@@ -791,19 +806,14 @@ fn infer_expr_type(analyzer: &Analyzer<'_>, expr: &Expr, state: &BodyState) -> O
791806 }
792807}
793808
794- fn infer_call_type ( analyzer : & Analyzer < ' _ > , callee : & Callee ) -> Option < String > {
795- if let Some ( signature) = analyzer. resolve_callee ( callee)
796- && let Some ( return_type) = & signature. return_type
797- {
798- return Some ( return_type. clone ( ) ) ;
799- }
800-
801- match callee {
802- Callee :: Name ( name) if analyzer. hir . type_info ( name) . is_some ( ) => Some ( name. clone ( ) ) ,
803- Callee :: Qualified { namespace, name } if name == "new" => {
804- analyzer. hir . type_info ( namespace) . map ( |_| namespace. clone ( ) )
805- }
806- Callee :: Name ( _) | Callee :: Qualified { .. } => None ,
809+ fn infer_call_type (
810+ analyzer : & Analyzer < ' _ > ,
811+ callee : & Callee ,
812+ span : & crate :: diagnostic:: Span ,
813+ ) -> Option < String > {
814+ match analyzer. resolve_call_site ( callee, span) {
815+ CallResolution :: Resolved { signature, .. } => signature. return_type ,
816+ CallResolution :: EnumVariant | CallResolution :: Unknown => None ,
807817 }
808818}
809819
0 commit comments