@@ -47,6 +47,7 @@ use crate::semantic_index::scope::{
4747 FileScopeId , NodeWithScopeKey , NodeWithScopeKind , NodeWithScopeRef ,
4848} ;
4949use crate :: semantic_index:: scope:: { Scope , ScopeId , ScopeKind , ScopeLaziness } ;
50+ use crate :: semantic_index:: statement:: { Statement , StatementNodeKey } ;
5051use crate :: semantic_index:: symbol:: { ScopedSymbolId , Symbol } ;
5152use crate :: semantic_index:: use_def:: {
5253 EnclosingSnapshotKey , FlowSnapshot , PreviousDefinitions , ScopedDefinitionId ,
@@ -100,6 +101,8 @@ pub(super) struct SemanticIndexBuilder<'db, 'ast> {
100101 /// The assignments we're currently visiting, with
101102 /// the most recent visit at the end of the Vec
102103 current_assignments : Vec < CurrentAssignment < ' ast , ' db > > ,
104+ /// The statement we're currently visiting.
105+ current_statement : Option < ( & ' ast ast:: Stmt , FileScopeId ) > ,
103106 /// The match case we're currently visiting.
104107 current_match_case : Option < CurrentMatchCase < ' ast > > ,
105108 /// The name of the first function parameter of the innermost function that we're currently visiting.
@@ -129,6 +132,8 @@ pub(super) struct SemanticIndexBuilder<'db, 'ast> {
129132 scopes_by_expression : ExpressionsScopeMapBuilder ,
130133 definitions_by_node : FxHashMap < DefinitionNodeKey , Definitions < ' db > > ,
131134 expressions_by_node : FxHashMap < ExpressionNodeKey , Expression < ' db > > ,
135+ statements_by_node : FxHashMap < StatementNodeKey , Statement < ' db > > ,
136+ enclosing_lambda_statements : FxHashMap < ExpressionNodeKey , Statement < ' db > > ,
132137 imported_modules : FxHashSet < ModuleName > ,
133138 seen_submodule_imports : FxHashSet < String > ,
134139 /// Hashset of all [`FileScopeId`]s that correspond to [generator functions].
@@ -150,6 +155,7 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
150155 module : module_ref,
151156 scope_stack : Vec :: new ( ) ,
152157 current_assignments : vec ! [ ] ,
158+ current_statement : None ,
153159 current_match_case : None ,
154160 current_first_parameter_name : None ,
155161 try_node_context_stack_manager : TryNodeContextStackManager :: default ( ) ,
@@ -167,6 +173,8 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
167173 scopes_by_node : FxHashMap :: default ( ) ,
168174 definitions_by_node : FxHashMap :: default ( ) ,
169175 expressions_by_node : FxHashMap :: default ( ) ,
176+ statements_by_node : FxHashMap :: default ( ) ,
177+ enclosing_lambda_statements : FxHashMap :: default ( ) ,
170178
171179 seen_submodule_imports : FxHashSet :: default ( ) ,
172180 imported_modules : FxHashSet :: default ( ) ,
@@ -1493,6 +1501,22 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
14931501 expression
14941502 }
14951503
1504+ fn add_standalone_statement (
1505+ & mut self ,
1506+ statement_node : & ast:: Stmt ,
1507+ scope : FileScopeId ,
1508+ ) -> Statement < ' db > {
1509+ let statement = Statement :: new (
1510+ self . db ,
1511+ self . file ,
1512+ scope,
1513+ AstNodeRef :: new ( self . module , statement_node) ,
1514+ ) ;
1515+ self . statements_by_node
1516+ . insert ( statement_node. into ( ) , statement) ;
1517+ statement
1518+ }
1519+
14961520 fn with_type_params (
14971521 & mut self ,
14981522 with_scope : NodeWithScopeRef ,
@@ -1858,6 +1882,8 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
18581882 use_def_maps. shrink_to_fit ( ) ;
18591883 ast_ids. shrink_to_fit ( ) ;
18601884 self . definitions_by_node . shrink_to_fit ( ) ;
1885+ self . statements_by_node . shrink_to_fit ( ) ;
1886+ self . enclosing_lambda_statements . shrink_to_fit ( ) ;
18611887
18621888 self . scope_ids_by_scope . shrink_to_fit ( ) ;
18631889 self . scopes_by_node . shrink_to_fit ( ) ;
@@ -1869,11 +1895,13 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
18691895 scopes : self . scopes ,
18701896 definitions_by_node : self . definitions_by_node ,
18711897 expressions_by_node : self . expressions_by_node ,
1898+ statements_by_node : self . statements_by_node ,
18721899 scope_ids_by_scope : self . scope_ids_by_scope ,
18731900 ast_ids,
18741901 scopes_by_expression : self . scopes_by_expression . build ( ) ,
18751902 scopes_by_node : self . scopes_by_node ,
18761903 use_def_maps,
1904+ enclosing_lambda_statements : self . enclosing_lambda_statements ,
18771905 imported_modules : Arc :: new ( self . imported_modules ) ,
18781906 has_future_annotations : self . has_future_annotations ,
18791907 enclosing_snapshots : self . enclosing_snapshots ,
@@ -1892,10 +1920,8 @@ impl<'db, 'ast> SemanticIndexBuilder<'db, 'ast> {
18921920 self . source_text
18931921 . get_or_init ( || source_text ( self . db , self . file ) )
18941922 }
1895- }
18961923
1897- impl < ' ast > Visitor < ' ast > for SemanticIndexBuilder < ' _ , ' ast > {
1898- fn visit_stmt ( & mut self , stmt : & ' ast ast:: Stmt ) {
1924+ fn visit_stmt_impl ( & mut self , stmt : & ' ast ast:: Stmt ) {
18991925 self . with_semantic_checker ( |semantic, context| semantic. visit_stmt ( stmt, context) ) ;
19001926
19011927 self . current_use_def_map_mut ( )
@@ -3107,6 +3133,14 @@ impl<'ast> Visitor<'ast> for SemanticIndexBuilder<'_, 'ast> {
31073133 }
31083134 }
31093135 }
3136+ }
3137+
3138+ impl < ' ast > Visitor < ' ast > for SemanticIndexBuilder < ' _ , ' ast > {
3139+ fn visit_stmt ( & mut self , stmt : & ' ast ast:: Stmt ) {
3140+ self . current_statement = Some ( ( stmt, self . current_scope ( ) ) ) ;
3141+ self . visit_stmt_impl ( stmt) ;
3142+ self . current_statement = None ;
3143+ }
31103144
31113145 fn visit_keyword ( & mut self , keyword : & ' ast ast:: Keyword ) {
31123146 walk_keyword ( self , keyword) ;
@@ -3238,6 +3272,15 @@ impl<'ast> Visitor<'ast> for SemanticIndexBuilder<'_, 'ast> {
32383272 }
32393273 }
32403274 ast:: Expr :: Lambda ( lambda) => {
3275+ // The body of a lambda expression needs access to the `Callable` type
3276+ // context the lambda is being inferred with, and so any statement
3277+ // containing a lambda must be inferable as a standalone statement.
3278+ if let Some ( ( stmt, scope) ) = self . current_statement {
3279+ let standalone_stmt = self . add_standalone_statement ( stmt, scope) ;
3280+ self . enclosing_lambda_statements
3281+ . insert ( lambda. into ( ) , standalone_stmt) ;
3282+ }
3283+
32413284 if let Some ( parameters) = & lambda. parameters {
32423285 // The default value of the parameters needs to be evaluated in the
32433286 // enclosing scope.
0 commit comments