From 6e9130bbf22da7971fd5178c2a4167dc46c43b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Matos?= Date: Tue, 18 Jun 2024 00:45:32 +0100 Subject: [PATCH] Unify namespace import logic for parsed and typed declarations (#6057) ## Description This PR unifies the logic for namespace imports so it works for parsed and typed declarations. This allows the soon-to-be-introduced AST resolving pass and collection context to correctly resolve imports. ## 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). - [x] 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. --- forc-pkg/src/pkg.rs | 15 +- sway-core/src/language/parsed/declaration.rs | 6 +- sway-core/src/lib.rs | 5 +- .../src/semantic_analysis/ast_node/mod.rs | 103 ++++++++++++- .../semantic_analysis/collection_context.rs | 90 +++++++++++ .../namespace/lexical_scope.rs | 33 ++-- .../src/semantic_analysis/namespace/root.rs | 143 ++++++++++++++---- sway-core/src/semantic_analysis/program.rs | 10 +- 8 files changed, 336 insertions(+), 69 deletions(-) diff --git a/forc-pkg/src/pkg.rs b/forc-pkg/src/pkg.rs index e6c53cb13f8..09b00fa5057 100644 --- a/forc-pkg/src/pkg.rs +++ b/forc-pkg/src/pkg.rs @@ -1645,17 +1645,20 @@ pub fn dependency_namespace( if let Some(core_node) = find_core_dep(graph, node) { let core_namespace = &lib_namespace_map[&core_node]; root_module.insert_submodule(CORE.to_string(), core_namespace.clone()); + core_added = true; } } let mut root = namespace::Root::from(root_module); - let _ = root.star_import_with_reexports( - &Handler::default(), - engines, - &[CORE, PRELUDE].map(|s| Ident::new_no_span(s.into())), - &[], - ); + if core_added { + let _ = root.star_import_with_reexports( + &Handler::default(), + engines, + &[CORE, PRELUDE].map(|s| Ident::new_no_span(s.into())), + &[], + ); + } if has_std_dep(graph, node) { let _ = root.star_import_with_reexports( diff --git a/sway-core/src/language/parsed/declaration.rs b/sway-core/src/language/parsed/declaration.rs index 638c2ffd3ae..374198cb53c 100644 --- a/sway-core/src/language/parsed/declaration.rs +++ b/sway-core/src/language/parsed/declaration.rs @@ -128,6 +128,9 @@ impl Declaration { } Declaration::StructDeclaration(decl_id) => decl_engine.get_struct(decl_id).visibility, Declaration::EnumDeclaration(decl_id) => decl_engine.get_enum(decl_id).visibility, + Declaration::EnumVariantDeclaration(decl) => { + decl_engine.get_enum(&decl.enum_ref).visibility + } Declaration::FunctionDeclaration(decl_id) => { decl_engine.get_function(decl_id).visibility } @@ -139,8 +142,7 @@ impl Declaration { | Declaration::ImplSelf(_) | Declaration::StorageDeclaration(_) | Declaration::AbiDeclaration(_) - | Declaration::TraitTypeDeclaration(_) - | Declaration::EnumVariantDeclaration(_) => Visibility::Public, + | Declaration::TraitTypeDeclaration(_) => Visibility::Public, } } } diff --git a/sway-core/src/lib.rs b/sway-core/src/lib.rs index 9db81cdba45..153358ca0cf 100644 --- a/sway-core/src/lib.rs +++ b/sway-core/src/lib.rs @@ -535,16 +535,17 @@ pub fn parsed_to_ast( // Build the dependency graph for the submodules. build_module_dep_graph(handler, &mut parse_program.root)?; + let namespace = Namespace::init_root(initial_namespace); // Collect the program symbols. let _collection_ctx = - ty::TyProgram::collect(handler, engines, parse_program, initial_namespace.clone())?; + ty::TyProgram::collect(handler, engines, parse_program, namespace.clone())?; // Type check the program. let typed_program_opt = ty::TyProgram::type_check( handler, engines, parse_program, - initial_namespace, + namespace, package_name, build_config, ); diff --git a/sway-core/src/semantic_analysis/ast_node/mod.rs b/sway-core/src/semantic_analysis/ast_node/mod.rs index f3b651af91b..4ce77481489 100644 --- a/sway-core/src/semantic_analysis/ast_node/mod.rs +++ b/sway-core/src/semantic_analysis/ast_node/mod.rs @@ -34,7 +34,9 @@ impl ty::TyAstNode { node: &AstNode, ) -> Result<(), ErrorEmitted> { match node.content.clone() { - AstNodeContent::UseStatement(_stmt) => {} + AstNodeContent::UseStatement(stmt) => { + collect_use_statement(handler, engines, ctx, &stmt); + } AstNodeContent::IncludeStatement(_i) => (), AstNodeContent::Declaration(decl) => ty::TyDecl::collect(handler, engines, ctx, decl)?, AstNodeContent::Expression(_expr) => (), @@ -147,6 +149,8 @@ fn handle_item_trait_imports( let dst_mod = ctx.namespace.module(engines); for (_, (_, src, decl)) in dst_mod.current_items().use_item_synonyms.iter() { + let decl = decl.expect_typed_ref(); + let src_mod = root_mod.lookup_submodule(handler, engines, src)?; // if this is an enum or struct or function, import its implementations @@ -184,6 +188,103 @@ fn handle_item_trait_imports( Ok(()) } +fn collect_use_statement( + handler: &Handler, + engines: &Engines, + ctx: &mut SymbolCollectionContext, + stmt: &UseStatement, +) { + let mut is_external = false; + if let Some(submodule) = ctx + .namespace + .module(engines) + .submodule(engines, &[stmt.call_path[0].clone()]) + { + is_external |= submodule.read(engines, |m| m.is_external); + } + // We create an inner module for each module being processed during the collection. + // This does not play well with the existing way we use to lookup an external module. + // So check again starting from the root to make sure we find the right module. + // Clean this up once paths are normalized before collection and we can just rely on + // absolute paths. + if let Some(submodule) = ctx + .namespace + .root_module() + .submodule(engines, &[stmt.call_path[0].clone()]) + { + is_external |= submodule.read(engines, |m| m.is_external); + } + let path = if is_external || stmt.is_absolute { + stmt.call_path.clone() + } else { + ctx.namespace.prepend_module_path(&stmt.call_path) + }; + let _ = match stmt.import_type { + ImportType::Star => { + // try a standard starimport first + let star_import_handler = Handler::default(); + let import = ctx.star_import(&star_import_handler, engines, &path); + if import.is_ok() { + handler.append(star_import_handler); + import + } else { + // if it doesn't work it could be an enum star import + if let Some((enum_name, path)) = path.split_last() { + let variant_import_handler = Handler::default(); + let variant_import = + ctx.variant_star_import(&variant_import_handler, engines, path, enum_name); + if variant_import.is_ok() { + handler.append(variant_import_handler); + variant_import + } else { + handler.append(star_import_handler); + import + } + } else { + handler.append(star_import_handler); + import + } + } + } + ImportType::SelfImport(_) => ctx.self_import(handler, engines, &path, stmt.alias.clone()), + ImportType::Item(ref s) => { + // try a standard item import first + let item_import_handler = Handler::default(); + let import = + ctx.item_import(&item_import_handler, engines, &path, s, stmt.alias.clone()); + + if import.is_ok() { + handler.append(item_import_handler); + import + } else { + // if it doesn't work it could be an enum variant import + if let Some((enum_name, path)) = path.split_last() { + let variant_import_handler = Handler::default(); + let variant_import = ctx.variant_import( + &variant_import_handler, + engines, + path, + enum_name, + s, + stmt.alias.clone(), + ); + if variant_import.is_ok() { + handler.append(variant_import_handler); + variant_import + } else { + handler.append(item_import_handler); + import + } + } else { + handler.append(item_import_handler); + import + } + } + } + }; +} + +// To be removed once TypeCheckContext is ported to use SymbolCollectionContext. fn handle_use_statement( ctx: &mut TypeCheckContext<'_>, engines: &Engines, diff --git a/sway-core/src/semantic_analysis/collection_context.rs b/sway-core/src/semantic_analysis/collection_context.rs index f5add438a30..9a59bf32072 100644 --- a/sway-core/src/semantic_analysis/collection_context.rs +++ b/sway-core/src/semantic_analysis/collection_context.rs @@ -1,5 +1,6 @@ use crate::{ language::{parsed::Declaration, Visibility}, + namespace::ModulePath, semantic_analysis::Namespace, Engines, }; @@ -90,4 +91,93 @@ impl SymbolCollectionContext { ) }) } + + /// Returns a mutable reference to the current namespace. + pub fn namespace_mut(&mut self) -> &mut Namespace { + &mut self.namespace + } + + /// Returns a reference to the current namespace. + pub fn namespace(&self) -> &Namespace { + &self.namespace + } + + /// Short-hand for performing a [Module::star_import] with `mod_path` as the destination. + pub(crate) fn star_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &ModulePath, + ) -> Result<(), ErrorEmitted> { + let mod_path = self.namespace().mod_path.clone(); + self.namespace_mut() + .root + .star_import(handler, engines, src, &mod_path) + } + + /// Short-hand for performing a [Module::variant_star_import] with `mod_path` as the destination. + pub(crate) fn variant_star_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &ModulePath, + enum_name: &Ident, + ) -> Result<(), ErrorEmitted> { + let mod_path = self.namespace().mod_path.clone(); + self.namespace_mut() + .root + .variant_star_import(handler, engines, src, &mod_path, enum_name) + } + + /// Short-hand for performing a [Module::self_import] with `mod_path` as the destination. + pub(crate) fn self_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &ModulePath, + alias: Option, + ) -> Result<(), ErrorEmitted> { + let mod_path = self.namespace().mod_path.clone(); + self.namespace_mut() + .root + .self_import(handler, engines, src, &mod_path, alias) + } + + /// Short-hand for performing a [Module::item_import] with `mod_path` as the destination. + pub(crate) fn item_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &ModulePath, + item: &Ident, + alias: Option, + ) -> Result<(), ErrorEmitted> { + let mod_path = self.namespace().mod_path.clone(); + self.namespace_mut() + .root + .item_import(handler, engines, src, item, &mod_path, alias) + } + + /// Short-hand for performing a [Module::variant_import] with `mod_path` as the destination. + #[allow(clippy::too_many_arguments)] + pub(crate) fn variant_import( + &mut self, + handler: &Handler, + engines: &Engines, + src: &ModulePath, + enum_name: &Ident, + variant_name: &Ident, + alias: Option, + ) -> Result<(), ErrorEmitted> { + let mod_path = self.namespace().mod_path.clone(); + self.namespace_mut().root.variant_import( + handler, + engines, + src, + enum_name, + variant_name, + &mod_path, + alias, + ) + } } diff --git a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs index 4e471633fd0..3c989c07073 100644 --- a/sway-core/src/semantic_analysis/namespace/lexical_scope.rs +++ b/sway-core/src/semantic_analysis/namespace/lexical_scope.rs @@ -37,8 +37,9 @@ impl ResolvedFunctionDecl { pub(super) type SymbolMap = im::OrdMap; type SourceIdent = Ident; -pub(super) type GlobSynonyms = im::HashMap>; -pub(super) type ItemSynonyms = im::HashMap, ModulePathBuf, ty::TyDecl)>; +pub(super) type GlobSynonyms = im::HashMap>; +pub(super) type ItemSynonyms = + im::HashMap, ModulePathBuf, ResolvedDeclaration)>; /// Represents a lexical scope integer-based identifier, which can be used to reference /// specific a lexical scope. @@ -66,23 +67,17 @@ pub struct Items { /// An ordered map from `Ident`s to their associated declarations. pub(crate) symbols: SymbolMap, pub(crate) implemented_traits: TraitMap, - /// Represents the absolute path from which a symbol was imported. - /// - /// For example, in `use ::foo::bar::Baz;`, we store a mapping from the symbol `Baz` to its - /// path `foo::bar::Baz`. - /// - /// use_glob_synonyms contains symbols imported using star imports (`use foo::*`.). + /// Contains symbols imported using star imports (`use foo::*`.). /// /// When star importing from multiple modules the same name may be imported more than once. This /// is not an error, but it is an error to use the name without a module path. To represent /// this, use_glob_synonyms maps identifiers to a vector of (module path, type declaration) /// tuples. - /// - /// use_item_synonyms contains symbols imported using item imports (`use foo::bar`). + pub(crate) use_glob_synonyms: GlobSynonyms, + /// Contains symbols imported using item imports (`use foo::bar`). /// /// For aliased item imports `use ::foo::bar::Baz as Wiz` the map key is `Wiz`. `Baz` is stored /// as the optional source identifier for error reporting purposes. - pub(crate) use_glob_synonyms: GlobSynonyms, pub(crate) use_item_synonyms: ItemSynonyms, /// If there is a storage declaration (which are only valid in contracts), store it here. pub(crate) declared_storage: Option, @@ -436,11 +431,11 @@ impl Items { item: &ResolvedDeclaration, const_shadowing_mode: ConstShadowingMode| { match (decl, item) { - (ResolvedDeclaration::Parsed(_decl), ResolvedDeclaration::Parsed(_item)) => { - // TODO: Do not handle any shadowing errors while handling parsed declarations yet, - // or else we will emit errors in a different order from the source code order. - // Update this once the full AST resolving pass is in. - } + // TODO: Do not handle any shadowing errors while handling parsed declarations yet, + // or else we will emit errors in a different order from the source code order. + // Update this once the full AST resolving pass is in. + (ResolvedDeclaration::Typed(_decl), ResolvedDeclaration::Parsed(_item)) => {} + (ResolvedDeclaration::Parsed(_decl), ResolvedDeclaration::Parsed(_item)) => {} (ResolvedDeclaration::Typed(decl), ResolvedDeclaration::Typed(item)) => { append_shadowing_error_typed( ident, @@ -469,12 +464,12 @@ impl Items { if let Some((ident, (imported_ident, _, decl))) = self.use_item_synonyms.get_key_value(&name) { - append_shadowing_error_typed( + append_shadowing_error( ident, decl, true, imported_ident.is_some(), - item.expect_typed_ref(), + &item, const_shadowing_mode, ); } @@ -495,7 +490,7 @@ impl Items { engines: &Engines, symbol: Ident, src_path: ModulePathBuf, - decl: &ty::TyDecl, + decl: &ResolvedDeclaration, ) { if let Some(cur_decls) = self.use_glob_synonyms.get_mut(&symbol) { // Name already bound. Check if the decl is already imported diff --git a/sway-core/src/semantic_analysis/namespace/root.rs b/sway-core/src/semantic_analysis/namespace/root.rs index 6008c7144c7..555efb33801 100644 --- a/sway-core/src/semantic_analysis/namespace/root.rs +++ b/sway-core/src/semantic_analysis/namespace/root.rs @@ -43,7 +43,30 @@ impl DebugWithEngines for ResolvedDeclaration { } } +impl PartialEqWithEngines for ResolvedDeclaration { + fn eq(&self, other: &Self, ctx: &PartialEqWithEnginesContext) -> bool { + match (self, other) { + (ResolvedDeclaration::Parsed(lhs), ResolvedDeclaration::Parsed(rhs)) => { + lhs.eq(rhs, ctx) + } + (ResolvedDeclaration::Typed(lhs), ResolvedDeclaration::Typed(rhs)) => lhs.eq(rhs, ctx), + // TODO: Right now we consider differently represented resolved declarations to not be + // equal. This is only used for comparing paths when doing imports, and we will be able + // to safely remove it once we introduce normalized paths. + (ResolvedDeclaration::Parsed(_lhs), ResolvedDeclaration::Typed(_rhs)) => false, + (ResolvedDeclaration::Typed(_lhs), ResolvedDeclaration::Parsed(_rhs)) => false, + } + } +} + impl ResolvedDeclaration { + pub fn expect_parsed(self) -> Declaration { + match self { + ResolvedDeclaration::Parsed(decl) => decl, + ResolvedDeclaration::Typed(_ty_decl) => panic!(), + } + } + pub fn expect_typed(self) -> ty::TyDecl { match self { ResolvedDeclaration::Parsed(_) => panic!(), @@ -117,7 +140,7 @@ impl Root { engines, symbol.clone(), src.to_vec(), - decl.expect_typed_ref(), + decl, ) }); @@ -172,7 +195,7 @@ impl Root { handler.emit_err(CompileError::ShadowsOtherSymbol { name: name.into() }); } }; - let decl = decl.expect_typed(); + match alias { Some(alias) => { check_name_clash(&alias); @@ -257,11 +280,13 @@ impl Root { ( Some(variant_name.clone()), src.to_vec(), - TyDecl::EnumVariantDecl(ty::EnumVariantDecl { - enum_ref: enum_ref.clone(), - variant_name: variant_name.clone(), - variant_decl_span: variant_decl.span.clone(), - }), + ResolvedDeclaration::Typed(TyDecl::EnumVariantDecl( + ty::EnumVariantDecl { + enum_ref: enum_ref.clone(), + variant_name: variant_name.clone(), + variant_decl_span: variant_decl.span.clone(), + }, + )), ), ); } @@ -272,11 +297,13 @@ impl Root { ( None, src.to_vec(), - TyDecl::EnumVariantDecl(ty::EnumVariantDecl { - enum_ref: enum_ref.clone(), - variant_name: variant_name.clone(), - variant_decl_span: variant_decl.span.clone(), - }), + ResolvedDeclaration::Typed(TyDecl::EnumVariantDecl( + ty::EnumVariantDecl { + enum_ref: enum_ref.clone(), + variant_name: variant_name.clone(), + variant_decl_span: variant_decl.span.clone(), + }, + )), ), ); } @@ -318,10 +345,13 @@ impl Root { ) -> Result<(), ErrorEmitted> { self.check_module_privacy(handler, engines, src)?; + let parsed_decl_engine = engines.pe(); let decl_engine = engines.de(); let src_mod = self.module.lookup_submodule(handler, engines, src)?; - match src_mod.current_items().symbols.get(enum_name).cloned() { + let resolved_decl = src_mod.current_items().symbols.get(enum_name).cloned(); + + match resolved_decl { Some(decl) => { if !decl.visibility(engines).is_public() && !is_ancestor(src, dst) { handler.emit_err(CompileError::ImportPrivateSymbol { @@ -330,7 +360,34 @@ impl Root { }); } - if let TyDecl::EnumDecl(ty::EnumDecl { decl_id, .. }) = decl.expect_typed() { + if let ResolvedDeclaration::Parsed(Declaration::EnumDeclaration(decl_id)) = decl { + let enum_decl = parsed_decl_engine.get_enum(&decl_id); + + for variant in enum_decl.variants.iter() { + let variant_name = &variant.name; + let variant_decl = + Declaration::EnumVariantDeclaration(EnumVariantDeclaration { + enum_ref: decl_id, + variant_name: variant_name.clone(), + variant_decl_span: variant.span.clone(), + }); + + // import it this way. + self.module + .lookup_submodule_mut(handler, engines, dst)? + .current_items_mut() + .insert_glob_use_symbol( + engines, + variant_name.clone(), + src.to_vec(), + &ResolvedDeclaration::Parsed(variant_decl), + ); + } + } else if let ResolvedDeclaration::Typed(TyDecl::EnumDecl(ty::EnumDecl { + decl_id, + .. + })) = decl + { let enum_decl = decl_engine.get_enum(&decl_id); let enum_ref = DeclRef::new( enum_decl.call_path.suffix.clone(), @@ -340,11 +397,13 @@ impl Root { for variant_decl in enum_decl.variants.iter() { let variant_name = &variant_decl.name; - let decl = TyDecl::EnumVariantDecl(ty::EnumVariantDecl { - enum_ref: enum_ref.clone(), - variant_name: variant_name.clone(), - variant_decl_span: variant_decl.span.clone(), - }); + let decl = ResolvedDeclaration::Typed(TyDecl::EnumVariantDecl( + ty::EnumVariantDecl { + enum_ref: enum_ref.clone(), + variant_name: variant_name.clone(), + variant_decl_span: variant_decl.span.clone(), + }, + )); // import it this way. self.module @@ -397,7 +456,7 @@ impl Root { let use_glob_synonyms = src_mod.current_items().use_glob_synonyms.clone(); // collect all declared and reexported symbols from the source module - let mut all_symbols_and_decls = vec![]; + let mut all_symbols_and_decls: Vec<(Ident, ResolvedDeclaration)> = vec![]; for (symbol, decls) in src_mod.current_items().use_glob_synonyms.iter() { decls .iter() @@ -408,7 +467,7 @@ impl Root { } for (symbol, decl) in src_mod.current_items().symbols.iter() { if is_ancestor(src, dst) || decl.visibility(engines).is_public() { - all_symbols_and_decls.push((symbol.clone(), decl.clone().expect_typed())); + all_symbols_and_decls.push((symbol.clone(), decl.clone())); } } @@ -448,7 +507,7 @@ impl Root { .implemented_traits .extend(implemented_traits, engines); - let mut try_add = |symbol, path, decl: ty::TyDecl| { + let mut try_add = |symbol, path, decl: ResolvedDeclaration| { dst_mod .current_items_mut() .insert_glob_use_symbol(engines, symbol, path, &decl); @@ -640,7 +699,8 @@ impl Root { current_mod_path.push(ident.clone()); } None => { - decl_opt = Some(self.resolve_symbol_helper(handler, ident, module)?); + decl_opt = + Some(self.resolve_symbol_helper(handler, engines, ident, module)?); } } } @@ -654,7 +714,7 @@ impl Root { self.module .lookup_submodule(handler, engines, mod_path) .and_then(|module| { - let decl = self.resolve_symbol_helper(handler, symbol, module)?; + let decl = self.resolve_symbol_helper(handler, engines, symbol, module)?; Ok((decl, mod_path.to_vec())) }) } @@ -810,21 +870,26 @@ impl Root { fn resolve_symbol_helper( &self, handler: &Handler, + engines: &Engines, symbol: &Ident, module: &Module, ) -> Result { + // Check locally declared items. Any name clash with imports will have already been reported as an error. + if let Some(decl) = module.current_items().symbols.get(symbol) { + return Ok(decl.clone()); + } // Check locally declared items. Any name clash with imports will have already been reported as an error. if let Some(decl) = module.current_items().symbols.get(symbol) { return Ok(decl.clone()); } // Check item imports if let Some((_, _, decl)) = module.current_items().use_item_synonyms.get(symbol) { - return Ok(ResolvedDeclaration::Typed(decl.clone())); + return Ok(decl.clone()); } // Check glob imports if let Some(decls) = module.current_items().use_glob_synonyms.get(symbol) { if decls.len() == 1 { - return Ok(ResolvedDeclaration::Typed(decls[0].1.clone())); + return Ok(decls[0].1.clone()); } else if decls.is_empty() { return Err(handler.emit_err(CompileError::Internal( "The name {symbol} was bound in a star import, but no corresponding module paths were found", @@ -837,14 +902,26 @@ impl Root { paths: decls .iter() .map(|(path, decl)| { - let mut path_strs = path.iter().map(|x| x.as_str()).collect::>(); + let mut path_strs = + path.iter().map(|x| x.to_string()).collect::>(); // Add the enum name to the path if the decl is an enum variant. - if let TyDecl::EnumVariantDecl(ty::EnumVariantDecl { - enum_ref, .. - }) = decl - { - path_strs.push(enum_ref.name().as_str()) - }; + match decl { + ResolvedDeclaration::Parsed(decl) => { + if let Declaration::EnumVariantDeclaration(decl) = decl { + let enum_ref = engines.pe().get_enum(&decl.enum_ref); + path_strs.push(enum_ref.name().to_string()) + }; + } + ResolvedDeclaration::Typed(decl) => { + if let TyDecl::EnumVariantDecl(ty::EnumVariantDecl { + enum_ref, + .. + }) = decl + { + path_strs.push(enum_ref.name().to_string()) + }; + } + } path_strs.join("::") }) .collect(), diff --git a/sway-core/src/semantic_analysis/program.rs b/sway-core/src/semantic_analysis/program.rs index d6705717e6e..71f73f359d7 100644 --- a/sway-core/src/semantic_analysis/program.rs +++ b/sway-core/src/semantic_analysis/program.rs @@ -5,7 +5,7 @@ use crate::{ }, metadata::MetadataManager, semantic_analysis::{ - namespace::{self, Namespace}, + namespace::{self}, TypeCheckContext, }, BuildConfig, Engines, @@ -27,9 +27,8 @@ impl TyProgram { handler: &Handler, engines: &Engines, parsed: &ParseProgram, - initial_namespace: namespace::Root, + namespace: namespace::Namespace, ) -> Result { - let namespace = Namespace::init_root(initial_namespace); let mut ctx = SymbolCollectionContext::new(namespace); let ParseProgram { root, kind: _ } = parsed; @@ -39,13 +38,13 @@ impl TyProgram { /// Type-check the given parsed program to produce a typed program. /// - /// The given `initial_namespace` acts as an initial state for each module within this program. + /// The given `namespace` acts as an initial state for each module within this program. /// It should contain a submodule for each library package dependency. pub fn type_check( handler: &Handler, engines: &Engines, parsed: &ParseProgram, - initial_namespace: namespace::Root, + mut namespace: namespace::Namespace, package_name: &str, build_config: Option<&BuildConfig>, ) -> Result { @@ -56,7 +55,6 @@ impl TyProgram { new_encoding: false, }); - let mut namespace = Namespace::init_root(initial_namespace); let mut ctx = TypeCheckContext::from_root(&mut namespace, engines, experimental) .with_kind(parsed.kind);