diff --git a/sway-core/src/semantic_analysis/symbol_resolve_context.rs b/sway-core/src/semantic_analysis/symbol_resolve_context.rs index 182ba74cda2..03661429ae5 100644 --- a/sway-core/src/semantic_analysis/symbol_resolve_context.rs +++ b/sway-core/src/semantic_analysis/symbol_resolve_context.rs @@ -9,7 +9,8 @@ use sway_error::handler::{ErrorEmitted, Handler}; use sway_types::{span::Span, Ident}; use super::{ - symbol_collection_context::SymbolCollectionContext, type_resolve::resolve_call_path, + symbol_collection_context::SymbolCollectionContext, + type_resolve::{resolve_call_path, VisibilityCheck}, GenericShadowingMode, }; @@ -190,6 +191,7 @@ impl<'a> SymbolResolveContext<'a> { &self.namespace().mod_path, call_path, self.self_type(), + VisibilityCheck::Yes, ) } } diff --git a/sway-core/src/semantic_analysis/type_check_context.rs b/sway-core/src/semantic_analysis/type_check_context.rs index 77e3a33e7bd..11c46c452f6 100644 --- a/sway-core/src/semantic_analysis/type_check_context.rs +++ b/sway-core/src/semantic_analysis/type_check_context.rs @@ -32,7 +32,7 @@ use super::{ symbol_collection_context::SymbolCollectionContext, type_resolve::{ resolve_call_path, resolve_call_path_and_mod_path, resolve_qualified_call_path, - resolve_symbol_and_mod_path, resolve_type, + resolve_symbol_and_mod_path, resolve_type, VisibilityCheck, }, GenericShadowingMode, }; @@ -674,6 +674,7 @@ impl<'a> TypeCheckContext<'a> { type_info_prefix, self.self_type(), &self.subst_ctx(), + VisibilityCheck::Yes, ) } @@ -690,6 +691,7 @@ impl<'a> TypeCheckContext<'a> { qualified_call_path, self.self_type(), &self.subst_ctx(), + VisibilityCheck::Yes, ) .map(|d| d.expect_typed()) } @@ -724,6 +726,7 @@ impl<'a> TypeCheckContext<'a> { &self.namespace().mod_path, call_path, self.self_type(), + VisibilityCheck::Yes, ) .map(|d| d.expect_typed()) } @@ -788,6 +791,7 @@ impl<'a> TypeCheckContext<'a> { None, self.self_type(), &self.subst_ctx(), + VisibilityCheck::Yes, ) .unwrap_or_else(|err| type_engine.id_of_error_recovery(err)); diff --git a/sway-core/src/semantic_analysis/type_resolve.rs b/sway-core/src/semantic_analysis/type_resolve.rs index caaa67f4d1a..991d32bcad6 100644 --- a/sway-core/src/semantic_analysis/type_resolve.rs +++ b/sway-core/src/semantic_analysis/type_resolve.rs @@ -16,6 +16,13 @@ use crate::{ EnforceTypeArguments, Engines, Namespace, SubstTypesContext, TypeId, TypeInfo, }; +/// Specifies if visibility checks should be performed as part of name resolution. +#[derive(Clone, Copy, PartialEq)] +pub enum VisibilityCheck { + Yes, + No, +} + /// Resolve the type of the given [TypeId], replacing any instances of /// [TypeInfo::Custom] with either a monomorphized struct, monomorphized /// enum, or a reference to a type parameter. @@ -31,6 +38,7 @@ pub fn resolve_type( type_info_prefix: Option<&ModulePath>, self_type: Option, subst_ctx: &SubstTypesContext, + check_visibility: VisibilityCheck, ) -> Result { let type_engine = engines.te(); let module_path = type_info_prefix.unwrap_or(mod_path); @@ -47,6 +55,7 @@ pub fn resolve_type( &qualified_call_path, self_type, subst_ctx, + check_visibility, ) .ok(); type_decl_opt_to_type_id( @@ -75,6 +84,7 @@ pub fn resolve_type( None, self_type, subst_ctx, + check_visibility, ) .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); @@ -92,6 +102,7 @@ pub fn resolve_type( None, self_type, subst_ctx, + check_visibility, ) .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); @@ -110,6 +121,7 @@ pub fn resolve_type( None, self_type, subst_ctx, + check_visibility, ) .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); } @@ -156,6 +168,7 @@ pub fn resolve_type( None, self_type, subst_ctx, + check_visibility, ) .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); @@ -170,6 +183,7 @@ pub fn resolve_type( Ok(type_id) } +#[allow(clippy::too_many_arguments)] pub fn resolve_qualified_call_path( handler: &Handler, engines: &Engines, @@ -178,6 +192,7 @@ pub fn resolve_qualified_call_path( qualified_call_path: &QualifiedCallPath, self_type: Option, subst_ctx: &SubstTypesContext, + check_visibility: VisibilityCheck, ) -> Result { let type_engine = engines.te(); if let Some(qualified_path_root) = qualified_call_path.clone().qualified_path_root { @@ -194,6 +209,7 @@ pub fn resolve_qualified_call_path( mod_path, &qualified_call_path.clone().to_call_path(handler)?, self_type, + check_visibility, )?; type_decl_opt_to_type_id( handler, @@ -242,10 +258,19 @@ pub fn resolve_qualified_call_path( mod_path, &qualified_call_path.call_path, self_type, + check_visibility, ) } } +/// Resolve a symbol that is potentially prefixed with some path, e.g. `foo::bar::symbol`. +/// +/// This will concatenate the `mod_path` with the `call_path`'s prefixes and +/// then calling `resolve_symbol` with the resulting path and call_path's suffix. +/// +/// The `mod_path` is significant here as we assume the resolution is done within the +/// context of the module pointed to by `mod_path` and will only check the call path prefixes +/// and the symbol's own visibility. pub fn resolve_call_path_and_mod_path( handler: &Handler, engines: &Engines, @@ -269,14 +294,6 @@ pub fn resolve_call_path_and_mod_path( ) } -/// Resolve a symbol that is potentially prefixed with some path, e.g. `foo::bar::symbol`. -/// -/// This will concatenate the `mod_path` with the `call_path`'s prefixes and -/// then calling `resolve_symbol` with the resulting path and call_path's suffix. -/// -/// The `mod_path` is significant here as we assume the resolution is done within the -/// context of the module pointed to by `mod_path` and will only check the call path prefixes -/// and the symbol's own visibility. pub fn resolve_call_path( handler: &Handler, engines: &Engines, @@ -284,6 +301,7 @@ pub fn resolve_call_path( mod_path: &ModulePath, call_path: &CallPath, self_type: Option, + check_visibility: VisibilityCheck, ) -> Result { let (decl, mod_path) = resolve_call_path_and_mod_path( handler, @@ -294,6 +312,10 @@ pub fn resolve_call_path( self_type, )?; + if check_visibility == VisibilityCheck::No { + return Ok(decl); + } + // In case there is no mod path we don't need to check visibility if mod_path.is_empty() { return Ok(decl); diff --git a/sway-core/src/type_system/monomorphization.rs b/sway-core/src/type_system/monomorphization.rs index ffe432f2292..6eb6581e96a 100644 --- a/sway-core/src/type_system/monomorphization.rs +++ b/sway-core/src/type_system/monomorphization.rs @@ -11,7 +11,7 @@ use crate::{ CallPath, }, namespace::{ModulePath, ResolvedDeclaration}, - semantic_analysis::type_resolve::resolve_type, + semantic_analysis::type_resolve::{resolve_type, VisibilityCheck}, type_system::ast_elements::create_type_id::CreateTypeId, EnforceTypeArguments, Engines, Namespace, SubstTypes, SubstTypesContext, TypeArgument, TypeId, TypeParameter, TypeSubstMap, @@ -129,6 +129,7 @@ where None, self_type, subst_ctx, + VisibilityCheck::Yes, ) .unwrap_or_else(|err| engines.te().id_of_error_recovery(err)); }