From 36849be1e0048ff10cf39ce261a154b434e5e6fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Matos?= Date: Wed, 11 Dec 2024 04:56:09 +0000 Subject: [PATCH] Associate lexical scopes with their respective declarations. (#6780) This adds a mapping from a lexical scope to the declaration that lexically corresponds to it. This is necessary for some upcoming collection context PR. ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] I have added tests that prove my fix is effective or that my feature works. - [x] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers. --- .../semantic_analysis/ast_node/code_block.rs | 23 +++++++----- .../ast_node/declaration/abi.rs | 10 ++--- .../ast_node/declaration/enum.rs | 12 +++--- .../ast_node/declaration/function.rs | 10 ++--- .../ast_node/declaration/impl_trait.rs | 37 +++++++++++-------- .../ast_node/declaration/struct.rs | 15 ++++---- .../ast_node/declaration/trait.rs | 10 ++--- .../ast_node/declaration/trait_fn.rs | 12 +++--- .../ast_node/expression/typed_expression.rs | 2 +- .../namespace/lexical_scope.rs | 3 ++ .../src/semantic_analysis/namespace/module.rs | 7 +++- .../symbol_collection_context.rs | 13 ++++--- 12 files changed, 80 insertions(+), 74 deletions(-) diff --git a/sway-core/src/semantic_analysis/ast_node/code_block.rs b/sway-core/src/semantic_analysis/ast_node/code_block.rs index c82523f9395..02cf5e581e7 100644 --- a/sway-core/src/semantic_analysis/ast_node/code_block.rs +++ b/sway-core/src/semantic_analysis/ast_node/code_block.rs @@ -11,15 +11,20 @@ impl ty::TyCodeBlock { ctx: &mut SymbolCollectionContext, code_block: &CodeBlock, ) -> Result<(), ErrorEmitted> { - let _ = ctx.scoped(engines, code_block.whole_block_span.clone(), |scoped_ctx| { - let _ = code_block - .contents - .iter() - .map(|node| ty::TyAstNode::collect(handler, engines, scoped_ctx, node)) - .filter_map(|res| res.ok()) - .collect::>(); - Ok(()) - }); + let _ = ctx.scoped( + engines, + code_block.whole_block_span.clone(), + None, + |scoped_ctx| { + let _ = code_block + .contents + .iter() + .map(|node| ty::TyAstNode::collect(handler, engines, scoped_ctx, node)) + .filter_map(|res| res.ok()) + .collect::>(); + Ok(()) + }, + ); Ok(()) } diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs b/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs index a22fd3925f6..30db0276496 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/abi.rs @@ -39,14 +39,10 @@ impl ty::TyAbiDecl { decl_id: &ParsedDeclId, ) -> Result<(), ErrorEmitted> { let abi_decl = engines.pe().get_abi(decl_id); - ctx.insert_parsed_symbol( - handler, - engines, - abi_decl.name.clone(), - Declaration::AbiDeclaration(*decl_id), - )?; + let decl = Declaration::AbiDeclaration(*decl_id); + ctx.insert_parsed_symbol(handler, engines, abi_decl.name.clone(), decl.clone())?; - let _ = ctx.scoped(engines, abi_decl.span.clone(), |scoped_ctx| { + let _ = ctx.scoped(engines, abi_decl.span.clone(), Some(decl), |scoped_ctx| { abi_decl.interface_surface.iter().for_each(|item| { let _ = TyTraitItem::collect(handler, engines, scoped_ctx, item); }); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs index 5e4839c0172..5f564978960 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/enum.rs @@ -16,15 +16,13 @@ impl ty::TyEnumDecl { decl_id: &ParsedDeclId, ) -> Result<(), ErrorEmitted> { let enum_decl = engines.pe().get_enum(decl_id); - ctx.insert_parsed_symbol( - handler, - engines, - enum_decl.name.clone(), - Declaration::EnumDeclaration(*decl_id), - )?; + let decl = Declaration::EnumDeclaration(*decl_id); + ctx.insert_parsed_symbol(handler, engines, enum_decl.name.clone(), decl.clone())?; // create a namespace for the decl, used to create a scope for generics - let _ = ctx.scoped(engines, enum_decl.span.clone(), |mut _ctx| Ok(())); + let _ = ctx.scoped(engines, enum_decl.span.clone(), Some(decl), |mut _ctx| { + Ok(()) + }); Ok(()) } diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs index 69603909545..2b1fcd5d5a2 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/function.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/function.rs @@ -28,15 +28,11 @@ impl ty::TyFunctionDecl { decl_id: &ParsedDeclId, ) -> Result<(), ErrorEmitted> { let fn_decl = engines.pe().get_function(decl_id); - let _ = ctx.insert_parsed_symbol( - handler, - engines, - fn_decl.name.clone(), - Declaration::FunctionDeclaration(*decl_id), - ); + let decl = Declaration::FunctionDeclaration(*decl_id); + let _ = ctx.insert_parsed_symbol(handler, engines, fn_decl.name.clone(), decl.clone()); // create a namespace for the function - let _ = ctx.scoped(engines, fn_decl.span.clone(), |scoped_ctx| { + let _ = ctx.scoped(engines, fn_decl.span.clone(), Some(decl), |scoped_ctx| { TyCodeBlock::collect(handler, engines, scoped_ctx, &fn_decl.body) }); Ok(()) diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs index 87e2f23fcee..f881cbbef60 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/impl_trait.rs @@ -39,27 +39,34 @@ impl TyImplSelfOrTrait { decl_id: &ParsedDeclId, ) -> Result<(), ErrorEmitted> { let impl_trait = engines.pe().get_impl_self_or_trait(decl_id); + + let decl = Declaration::ImplSelfOrTrait(*decl_id); ctx.insert_parsed_symbol( handler, engines, impl_trait.trait_name.suffix.clone(), - Declaration::ImplSelfOrTrait(*decl_id), + decl.clone(), )?; - let _ = ctx.scoped(engines, impl_trait.block_span.clone(), |scoped_ctx| { - impl_trait.items.iter().for_each(|item| match item { - ImplItem::Fn(decl_id) => { - let _ = TyFunctionDecl::collect(handler, engines, scoped_ctx, decl_id); - } - ImplItem::Constant(decl_id) => { - let _ = TyConstantDecl::collect(handler, engines, scoped_ctx, decl_id); - } - ImplItem::Type(decl_id) => { - let _ = TyTraitType::collect(handler, engines, scoped_ctx, decl_id); - } - }); - Ok(()) - }); + let _ = ctx.scoped( + engines, + impl_trait.block_span.clone(), + Some(decl), + |scoped_ctx| { + impl_trait.items.iter().for_each(|item| match item { + ImplItem::Fn(decl_id) => { + let _ = TyFunctionDecl::collect(handler, engines, scoped_ctx, decl_id); + } + ImplItem::Constant(decl_id) => { + let _ = TyConstantDecl::collect(handler, engines, scoped_ctx, decl_id); + } + ImplItem::Type(decl_id) => { + let _ = TyTraitType::collect(handler, engines, scoped_ctx, decl_id); + } + }); + Ok(()) + }, + ); Ok(()) } diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs index 4ad0a268284..18e7a6e394e 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/struct.rs @@ -16,15 +16,16 @@ impl ty::TyStructDecl { decl_id: &ParsedDeclId, ) -> Result<(), ErrorEmitted> { let struct_decl = engines.pe().get_struct(decl_id); - ctx.insert_parsed_symbol( - handler, - engines, - struct_decl.name.clone(), - Declaration::StructDeclaration(*decl_id), - )?; + let decl = Declaration::StructDeclaration(*decl_id); + ctx.insert_parsed_symbol(handler, engines, struct_decl.name.clone(), decl.clone())?; // create a namespace for the decl, used to create a scope for generics - let _ = ctx.scoped(engines, struct_decl.span.clone(), |_scoped_ctx| Ok(())); + let _ = ctx.scoped( + engines, + struct_decl.span.clone(), + Some(decl), + |_scoped_ctx| Ok(()), + ); Ok(()) } diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs index 640fbc09b72..e25a568cb3d 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait.rs @@ -53,15 +53,11 @@ impl TyTraitDecl { decl_id: &ParsedDeclId, ) -> Result<(), ErrorEmitted> { let trait_decl = engines.pe().get_trait(decl_id); - ctx.insert_parsed_symbol( - handler, - engines, - trait_decl.name.clone(), - Declaration::TraitDeclaration(*decl_id), - )?; + let decl = Declaration::TraitDeclaration(*decl_id); + ctx.insert_parsed_symbol(handler, engines, trait_decl.name.clone(), decl.clone())?; // A temporary namespace for checking within the trait's scope. - let _ = ctx.scoped(engines, trait_decl.span.clone(), |scoped_ctx| { + let _ = ctx.scoped(engines, trait_decl.span.clone(), Some(decl), |scoped_ctx| { trait_decl.interface_surface.iter().for_each(|item| { let _ = TyTraitItem::collect(handler, engines, scoped_ctx, item); }); diff --git a/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs b/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs index fc2b0fc6c3f..0777b17bcf5 100644 --- a/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs +++ b/sway-core/src/semantic_analysis/ast_node/declaration/trait_fn.rs @@ -24,13 +24,11 @@ impl ty::TyTraitFn { decl_id: &ParsedDeclId, ) -> Result<(), ErrorEmitted> { let trait_fn = engines.pe().get_trait_fn(decl_id); - ctx.insert_parsed_symbol( - handler, - engines, - trait_fn.name.clone(), - Declaration::TraitFnDeclaration(*decl_id), - )?; - let _ = ctx.scoped(engines, trait_fn.span.clone(), |_scoped_ctx| Ok(())); + let decl = Declaration::TraitFnDeclaration(*decl_id); + ctx.insert_parsed_symbol(handler, engines, trait_fn.name.clone(), decl.clone())?; + let _ = ctx.scoped(engines, trait_fn.span.clone(), Some(decl), |_scoped_ctx| { + Ok(()) + }); Ok(()) } diff --git a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs index 0fa64d14598..06220dcac74 100644 --- a/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs +++ b/sway-core/src/semantic_analysis/ast_node/expression/typed_expression.rs @@ -216,7 +216,7 @@ impl ty::TyExpression { .iter() .map(|branch| { // create a new namespace for this branch result - ctx.scoped(engines, branch.span.clone(), |scoped_ctx| { + ctx.scoped(engines, branch.span.clone(), None, |scoped_ctx| { Self::collect(handler, engines, scoped_ctx, &branch.result) }) .0 diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index c0773f55110..308b5c0b989 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -71,6 +71,9 @@ pub struct LexicalScope { pub children: Vec, /// The parent scope associated with this scope. Will be None for a root scope. pub parent: Option, + /// The declaration associated with this scope. This will initially be a [ParsedDeclId], + /// but can be replaced to be a [DeclId] once the declaration is type checked. + pub declaration: Option, } /// The set of items that exist within some lexical scope via declaration or importing. diff --git a/sway-core/src/semantic_analysis/namespace/module.rs b/sway-core/src/semantic_analysis/namespace/module.rs index 319f4abb247..af89e4469c9 100644 --- a/sway-core/src/semantic_analysis/namespace/module.rs +++ b/sway-core/src/semantic_analysis/namespace/module.rs @@ -277,11 +277,16 @@ impl Module { } /// Pushes a new scope to the module's lexical scope hierarchy. - pub fn push_new_lexical_scope(&mut self, span: Span) -> LexicalScopeId { + pub fn push_new_lexical_scope( + &mut self, + span: Span, + declaration: Option, + ) -> LexicalScopeId { let previous_scope_id = self.current_lexical_scope_id(); let new_scoped_id = { self.lexical_scopes.push(LexicalScope { parent: Some(previous_scope_id), + declaration, ..Default::default() }); self.lexical_scopes.len() - 1 diff --git a/sway-core/src/semantic_analysis/symbol_collection_context.rs b/sway-core/src/semantic_analysis/symbol_collection_context.rs index 2a3be6aa35d..f831c2226ea 100644 --- a/sway-core/src/semantic_analysis/symbol_collection_context.rs +++ b/sway-core/src/semantic_analysis/symbol_collection_context.rs @@ -1,7 +1,6 @@ use crate::{ language::{parsed::Declaration, Visibility}, - namespace::LexicalScopeId, - namespace::ModulePath, + namespace::{LexicalScopeId, ModulePath, ResolvedDeclaration}, semantic_analysis::Namespace, Engines, }; @@ -41,12 +40,14 @@ impl SymbolCollectionContext { &mut self, engines: &Engines, span: Span, + decl: Option, with_scoped_ctx: impl FnOnce(&mut SymbolCollectionContext) -> Result, ) -> (Result, LexicalScopeId) { - let lexical_scope_id: LexicalScopeId = self - .namespace - .module_mut(engines) - .write(engines, |m| m.push_new_lexical_scope(span.clone())); + let decl = decl.map(ResolvedDeclaration::Parsed); + let lexical_scope_id: LexicalScopeId = + self.namespace.module_mut(engines).write(engines, |m| { + m.push_new_lexical_scope(span.clone(), decl.clone()) + }); let ret = with_scoped_ctx(self); self.namespace .module_mut(engines)