From 2b70b08d5f637f2252e84c26d2fbda96385aaf7e Mon Sep 17 00:00:00 2001 From: Matheus Aguiar Date: Sun, 8 Jan 2023 23:14:17 -0300 Subject: [PATCH] Allow library external functions to be bound with using for --- Changelog.md | 1 + libsolidity/analysis/NameAndTypeResolver.cpp | 15 ++++++--- libsolidity/analysis/NameAndTypeResolver.h | 2 +- libsolidity/analysis/ReferencesResolver.cpp | 33 +++++++++++++++++++ libsolidity/analysis/ReferencesResolver.h | 1 + libsolidity/analysis/TypeChecker.cpp | 20 ++++++++--- .../library_functions_inside_contract.sol | 31 +++++++++++++++++ ...external_library_function_inside_scope.sol | 9 +++++ .../external_function_qualified_with_this.sol | 7 ++++ .../using/free_functions_non_unique_err.sol | 2 +- .../syntaxTests/using/free_overloads.sol | 2 +- .../using/free_overloads_array.sol | 2 +- ...rom_base_contract_qualified_with_super.sol | 9 +++++ ..._name_without_braces_at_file_level_err.sol | 11 +++++++ ...ame_without_braces_inside_contract_err.sol | 10 ++++++ .../interface_function_at_file_level.sol | 7 ++++ .../interface_function_inside_contract.sol | 9 +++++ .../using/library_at_file_level.sol | 17 ++++++++++ .../using/library_functions_at_file_level.sol | 19 +++++++++++ ...ched_at_file_level_used_inside_library.sol | 17 ++++++++++ ...ched_in_single_directive_at_file_level.sol | 17 ++++++++++ ...ed_in_single_directive_inside_contract.sol | 17 ++++++++++ .../library_functions_inside_contract.sol | 19 +++++++++++ .../using/library_inside_contract.sol | 17 ++++++++++ ...library_non_free_external_function_err.sol | 2 +- .../using/module_identifier_not_found.sol | 2 +- .../using/public_state_variable_getter.sol | 11 +++++++ .../syntaxTests/using/undeclared_library.sol | 3 ++ ...hed_in_single_directive_inside_library.sol | 19 +++++++++++ 29 files changed, 316 insertions(+), 15 deletions(-) create mode 100644 test/libsolidity/semanticTests/using/library_functions_inside_contract.sol create mode 100644 test/libsolidity/syntaxTests/scoping/external_library_function_inside_scope.sol create mode 100644 test/libsolidity/syntaxTests/using/external_function_qualified_with_this.sol create mode 100644 test/libsolidity/syntaxTests/using/function_from_base_contract_qualified_with_super.sol create mode 100644 test/libsolidity/syntaxTests/using/function_name_without_braces_at_file_level_err.sol create mode 100644 test/libsolidity/syntaxTests/using/function_name_without_braces_inside_contract_err.sol create mode 100644 test/libsolidity/syntaxTests/using/interface_function_at_file_level.sol create mode 100644 test/libsolidity/syntaxTests/using/interface_function_inside_contract.sol create mode 100644 test/libsolidity/syntaxTests/using/library_at_file_level.sol create mode 100644 test/libsolidity/syntaxTests/using/library_functions_at_file_level.sol create mode 100644 test/libsolidity/syntaxTests/using/library_functions_attached_at_file_level_used_inside_library.sol create mode 100644 test/libsolidity/syntaxTests/using/library_functions_attached_in_single_directive_at_file_level.sol create mode 100644 test/libsolidity/syntaxTests/using/library_functions_attached_in_single_directive_inside_contract.sol create mode 100644 test/libsolidity/syntaxTests/using/library_functions_inside_contract.sol create mode 100644 test/libsolidity/syntaxTests/using/library_inside_contract.sol create mode 100644 test/libsolidity/syntaxTests/using/public_state_variable_getter.sol create mode 100644 test/libsolidity/syntaxTests/using/undeclared_library.sol create mode 100644 test/libsolidity/syntaxTests/using/unqualified_library_functions_attached_in_single_directive_inside_library.sol diff --git a/Changelog.md b/Changelog.md index 8a3bfae6a..7619fbd40 100644 --- a/Changelog.md +++ b/Changelog.md @@ -7,6 +7,7 @@ Compiler Features: Bugfixes: + * TypeChecker: Also allow external library functions in ``using for``. ### 0.8.18 (2023-02-01) diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 1b58d3c9a..641f02280 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -195,16 +195,23 @@ Declaration const* NameAndTypeResolver::pathFromCurrentScope(vector c return nullptr; } -std::vector NameAndTypeResolver::pathFromCurrentScopeWithAllDeclarations(std::vector const& _path) const +std::vector NameAndTypeResolver::pathFromCurrentScopeWithAllDeclarations( + std::vector const& _path, + bool _includeInvisibles +) const { solAssert(!_path.empty(), ""); vector pathDeclarations; ResolvingSettings settings; settings.recursive = true; - settings.alsoInvisible = false; + settings.alsoInvisible = _includeInvisibles; settings.onlyVisibleAsUnqualifiedNames = true; - vector candidates = m_currentScope->resolveName(_path.front(), std::move(settings)); + vector candidates = m_currentScope->resolveName(_path.front(), settings); + + // inside the loop, use default settings, except for alsoInvisible + settings.recursive = false; + settings.onlyVisibleAsUnqualifiedNames = false; for (size_t i = 1; i < _path.size() && candidates.size() == 1; i++) { @@ -213,7 +220,7 @@ std::vector NameAndTypeResolver::pathFromCurrentScopeWithAll pathDeclarations.push_back(candidates.front()); - candidates = m_scopes.at(candidates.front())->resolveName(_path[i]); + candidates = m_scopes.at(candidates.front())->resolveName(_path[i], settings); } if (candidates.size() == 1) { diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h index 2bf238a00..6ba591e8a 100644 --- a/libsolidity/analysis/NameAndTypeResolver.h +++ b/libsolidity/analysis/NameAndTypeResolver.h @@ -96,7 +96,7 @@ public: /// Resolves a path starting from the "current" scope, but also searches parent scopes. /// Should only be called during the initial resolving phase. /// @note Returns an empty vector if any component in the path was non-unique or not found. Otherwise, all declarations along the path are returned. - std::vector pathFromCurrentScopeWithAllDeclarations(std::vector const& _path) const; + std::vector pathFromCurrentScopeWithAllDeclarations(std::vector const& _path, bool _includeInvisibles = false) const; /// Generate and store warnings about declarations with the same name. void warnHomonymDeclarations() const; diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 50b1656ef..399c15b56 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -173,6 +173,7 @@ void ReferencesResolver::endVisit(ModifierDefinition const&) void ReferencesResolver::endVisit(IdentifierPath const& _path) { + // Note that library/functions names in "using {} for" directive are resolved separately in visit(UsingForDirective) std::vector declarations = m_resolver.pathFromCurrentScopeWithAllDeclarations(_path.path()); if (declarations.empty()) { @@ -184,6 +185,38 @@ void ReferencesResolver::endVisit(IdentifierPath const& _path) _path.annotation().pathDeclarations = std::move(declarations); } +bool ReferencesResolver::visit(UsingForDirective const& _usingFor) +{ + for (ASTPointer const& path: _usingFor.functionsOrLibrary()) + { + // _includeInvisibles is enabled here because external library functions are marked invisible. + // As unintended side-effects other invisible names (eg.: super, this) may be returned as well. + // DeclarationTypeChecker should detect and report such situations. + vector declarations = m_resolver.pathFromCurrentScopeWithAllDeclarations(path->path(), true /* _includeInvisibles */); + if (declarations.empty()) + { + string libraryOrFunctionNameErrorMessage = + _usingFor.usesBraces() ? + "Identifier is not a function name or not unique." : + "Identifier is not a library name."; + m_errorReporter.fatalDeclarationError( + 9589_error, + path->location(), + libraryOrFunctionNameErrorMessage + ); + break; + } + + path->annotation().referencedDeclaration = declarations.back(); + path->annotation().pathDeclarations = std::move(declarations); + } + + if (_usingFor.typeName()) + _usingFor.typeName()->accept(*this); + + return false; +} + bool ReferencesResolver::visit(InlineAssembly const& _inlineAssembly) { m_yulAnnotation = &_inlineAssembly.annotation(); diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h index 530100a24..512a681b4 100644 --- a/libsolidity/analysis/ReferencesResolver.h +++ b/libsolidity/analysis/ReferencesResolver.h @@ -84,6 +84,7 @@ private: void endVisit(IdentifierPath const& _path) override; bool visit(InlineAssembly const& _inlineAssembly) override; bool visit(Return const& _return) override; + bool visit(UsingForDirective const& _usingFor) override; void operator()(yul::FunctionDefinition const& _function) override; void operator()(yul::Identifier const& _identifier) override; diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 4e390931f..074b644b7 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -3826,7 +3826,13 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor) FunctionDefinition const& functionDefinition = dynamic_cast(*path->annotation().referencedDeclaration); - solAssert(functionDefinition.type()); + FunctionType const* functionType = dynamic_cast( + functionDefinition.libraryFunction() ? + functionDefinition.typeViaContractName() : + functionDefinition.type() + ); + + solAssert(functionType); if (functionDefinition.parameters().empty()) m_errorReporter.fatalTypeError( @@ -3864,21 +3870,25 @@ void TypeChecker::endVisit(UsingForDirective const& _usingFor) ); } - FunctionType const* functionType = dynamic_cast(*functionDefinition.type()).withBoundFirstArgument(); - solAssert(functionType && functionType->selfType(), ""); + FunctionType const* functionTypeWithBoundFirstArgument = functionType->withBoundFirstArgument(); + solAssert(functionTypeWithBoundFirstArgument && functionTypeWithBoundFirstArgument->selfType(), ""); BoolResult result = normalizedType->isImplicitlyConvertibleTo( - *TypeProvider::withLocationIfReference(DataLocation::Storage, functionType->selfType()) + *TypeProvider::withLocationIfReference(DataLocation::Storage, functionTypeWithBoundFirstArgument->selfType()) ); if (!result) m_errorReporter.typeError( 3100_error, path->location(), + SecondarySourceLocation().append( + "Function defined here:", + functionDefinition.location() + ), fmt::format( "The function \"{}\" cannot be attached to the type \"{}\" because the type cannot " "be implicitly converted to the first argument of the function (\"{}\"){}", joinHumanReadable(path->path(), "."), usingForType->toString(true /* withoutDataLocation */), - functionType->selfType()->humanReadableName(), + functionTypeWithBoundFirstArgument->selfType()->humanReadableName(), result.message().empty() ? "." : ": " + result.message() ) ); diff --git a/test/libsolidity/semanticTests/using/library_functions_inside_contract.sol b/test/libsolidity/semanticTests/using/library_functions_inside_contract.sol new file mode 100644 index 000000000..170bc7853 --- /dev/null +++ b/test/libsolidity/semanticTests/using/library_functions_inside_contract.sol @@ -0,0 +1,31 @@ +library L { + function externalFunction(uint a) external pure returns (uint) { return a * 1; } + function publicFunction(uint b) public pure returns (uint) { return b * 2; } + function internalFunction(uint c) internal pure returns (uint) { return c * 3; } +} + +contract C { + using {L.externalFunction} for uint; + using {L.publicFunction} for uint; + using {L.internalFunction} for uint; + + function f() public pure returns (uint) { + uint x = 1; + return x.externalFunction(); + } + + function g() public pure returns (uint) { + uint x = 1; + return x.publicFunction(); + } + + function h() public pure returns (uint) { + uint x = 1; + return x.internalFunction(); + } +} +// ---- +// library: L +// f() -> 1 +// g() -> 2 +// h() -> 3 diff --git a/test/libsolidity/syntaxTests/scoping/external_library_function_inside_scope.sol b/test/libsolidity/syntaxTests/scoping/external_library_function_inside_scope.sol new file mode 100644 index 000000000..647e5b416 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/external_library_function_inside_scope.sol @@ -0,0 +1,9 @@ +library L { + function externalFunction(uint) external pure {} + function f() public pure { + uint x; + externalFunction(x); + } +} +// ---- +// DeclarationError 7576: (120-136): Undeclared identifier. "externalFunction" is not (or not yet) visible at this point. diff --git a/test/libsolidity/syntaxTests/using/external_function_qualified_with_this.sol b/test/libsolidity/syntaxTests/using/external_function_qualified_with_this.sol new file mode 100644 index 000000000..2f4007605 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/external_function_qualified_with_this.sol @@ -0,0 +1,7 @@ +contract C { + using {this.contractFunction} for uint; + + function contractFunction(uint) external view {} +} +// ---- +// DeclarationError 9589: (24-45): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/using/free_functions_non_unique_err.sol b/test/libsolidity/syntaxTests/using/free_functions_non_unique_err.sol index 7536dff07..7404b0d9b 100644 --- a/test/libsolidity/syntaxTests/using/free_functions_non_unique_err.sol +++ b/test/libsolidity/syntaxTests/using/free_functions_non_unique_err.sol @@ -9,4 +9,4 @@ contract C { using {id} for uint256; } // ---- -// DeclarationError 7920: (145-147): Identifier not found or not unique. +// DeclarationError 9589: (145-147): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/using/free_overloads.sol b/test/libsolidity/syntaxTests/using/free_overloads.sol index 28a8e69ed..e05580d5f 100644 --- a/test/libsolidity/syntaxTests/using/free_overloads.sol +++ b/test/libsolidity/syntaxTests/using/free_overloads.sol @@ -7,4 +7,4 @@ function f(int8 storage x) pure returns (int) { using {f} for uint8; using {f} for int; // ---- -// DeclarationError 7920: (132-133): Identifier not found or not unique. +// DeclarationError 9589: (132-133): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/using/free_overloads_array.sol b/test/libsolidity/syntaxTests/using/free_overloads_array.sol index 91b807397..cab3eccf2 100644 --- a/test/libsolidity/syntaxTests/using/free_overloads_array.sol +++ b/test/libsolidity/syntaxTests/using/free_overloads_array.sol @@ -6,4 +6,4 @@ function f(uint x, uint y) pure returns (int) { } using {f} for uint; // ---- -// DeclarationError 7920: (138-139): Identifier not found or not unique. +// DeclarationError 9589: (138-139): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/using/function_from_base_contract_qualified_with_super.sol b/test/libsolidity/syntaxTests/using/function_from_base_contract_qualified_with_super.sol new file mode 100644 index 000000000..a162912ca --- /dev/null +++ b/test/libsolidity/syntaxTests/using/function_from_base_contract_qualified_with_super.sol @@ -0,0 +1,9 @@ +contract C { + function baseFunction(uint) public pure {} +} + +contract D is C { + using {super.baseFunction} for uint; +} +// ---- +// DeclarationError 9589: (92-110): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/using/function_name_without_braces_at_file_level_err.sol b/test/libsolidity/syntaxTests/using/function_name_without_braces_at_file_level_err.sol new file mode 100644 index 000000000..85d591fd4 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/function_name_without_braces_at_file_level_err.sol @@ -0,0 +1,11 @@ +function f(uint x) pure { } + +using f for uint; + +contract C { + function g(uint x) public pure { + x.f(); + } +} +// ---- +// TypeError 4357: (35-36): Library name expected. If you want to attach a function, use '{...}'. diff --git a/test/libsolidity/syntaxTests/using/function_name_without_braces_inside_contract_err.sol b/test/libsolidity/syntaxTests/using/function_name_without_braces_inside_contract_err.sol new file mode 100644 index 000000000..003137381 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/function_name_without_braces_inside_contract_err.sol @@ -0,0 +1,10 @@ +function f(uint x) pure { } + +contract C { + using f for uint; + function g(uint x) public pure { + x.f(); + } +} +// ---- +// TypeError 4357: (52-53): Library name expected. If you want to attach a function, use '{...}'. diff --git a/test/libsolidity/syntaxTests/using/interface_function_at_file_level.sol b/test/libsolidity/syntaxTests/using/interface_function_at_file_level.sol new file mode 100644 index 000000000..9a9ee26f6 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/interface_function_at_file_level.sol @@ -0,0 +1,7 @@ +interface I { + function g() external pure; +} + +using {I.g} for uint; +// ---- +// TypeError 4167: (56-59): Only file-level functions and library functions can be attached to a type in a "using" statement diff --git a/test/libsolidity/syntaxTests/using/interface_function_inside_contract.sol b/test/libsolidity/syntaxTests/using/interface_function_inside_contract.sol new file mode 100644 index 000000000..f01788ff5 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/interface_function_inside_contract.sol @@ -0,0 +1,9 @@ +interface I { + function g() external pure; +} + +contract C { + using {I.g} for uint; +} +// ---- +// TypeError 4167: (73-76): Only file-level functions and library functions can be attached to a type in a "using" statement diff --git a/test/libsolidity/syntaxTests/using/library_at_file_level.sol b/test/libsolidity/syntaxTests/using/library_at_file_level.sol new file mode 100644 index 000000000..9cb1965a0 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/library_at_file_level.sol @@ -0,0 +1,17 @@ +library L { + function externalFunction(uint) external pure {} + function publicFunction(uint) public pure {} + function internalFunction(uint) internal pure {} +} + +using L for uint; + +contract C { + function f() public pure { + uint x; + x.externalFunction(); + x.publicFunction(); + x.internalFunction(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/using/library_functions_at_file_level.sol b/test/libsolidity/syntaxTests/using/library_functions_at_file_level.sol new file mode 100644 index 000000000..2876f591a --- /dev/null +++ b/test/libsolidity/syntaxTests/using/library_functions_at_file_level.sol @@ -0,0 +1,19 @@ +library L { + function externalFunction(uint) external pure {} + function publicFunction(uint) public pure {} + function internalFunction(uint) internal pure {} +} + +using {L.externalFunction} for uint; +using {L.publicFunction} for uint; +using {L.internalFunction} for uint; + +contract C { + function f() public pure { + uint x; + x.externalFunction(); + x.publicFunction(); + x.internalFunction(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/using/library_functions_attached_at_file_level_used_inside_library.sol b/test/libsolidity/syntaxTests/using/library_functions_attached_at_file_level_used_inside_library.sol new file mode 100644 index 000000000..21d30f557 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/library_functions_attached_at_file_level_used_inside_library.sol @@ -0,0 +1,17 @@ +using {L.externalFunction, L.publicFunction, L.internalFunction} for uint; + +library L { + function externalFunction(uint) external pure {} + function publicFunction(uint) public pure {} + function internalFunction(uint) internal pure {} + + function f() public pure { + uint x; + x.externalFunction(); + x.publicFunction(); + x.internalFunction(); + } +} +// ---- +// TypeError 6700: (299-319): Libraries cannot call their own functions externally. +// TypeError 6700: (329-347): Libraries cannot call their own functions externally. diff --git a/test/libsolidity/syntaxTests/using/library_functions_attached_in_single_directive_at_file_level.sol b/test/libsolidity/syntaxTests/using/library_functions_attached_in_single_directive_at_file_level.sol new file mode 100644 index 000000000..bb191faa6 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/library_functions_attached_in_single_directive_at_file_level.sol @@ -0,0 +1,17 @@ +library L { + function externalFunction(uint) external pure {} + function publicFunction(uint) public pure {} + function internalFunction(uint) internal pure {} +} + +using {L.externalFunction, L.publicFunction, L.internalFunction} for uint; + +contract C { + function f() public pure { + uint x; + x.externalFunction(); + x.publicFunction(); + x.internalFunction(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/using/library_functions_attached_in_single_directive_inside_contract.sol b/test/libsolidity/syntaxTests/using/library_functions_attached_in_single_directive_inside_contract.sol new file mode 100644 index 000000000..300a3480d --- /dev/null +++ b/test/libsolidity/syntaxTests/using/library_functions_attached_in_single_directive_inside_contract.sol @@ -0,0 +1,17 @@ +library L { + function externalFunction(uint) external pure {} + function publicFunction(uint) public pure {} + function internalFunction(uint) internal pure {} +} + +contract C { + using {L.externalFunction, L.publicFunction, L.internalFunction} for uint; + + function f() public pure { + uint x; + x.externalFunction(); + x.publicFunction(); + x.internalFunction(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/using/library_functions_inside_contract.sol b/test/libsolidity/syntaxTests/using/library_functions_inside_contract.sol new file mode 100644 index 000000000..46d4c571d --- /dev/null +++ b/test/libsolidity/syntaxTests/using/library_functions_inside_contract.sol @@ -0,0 +1,19 @@ +library L { + function externalFunction(uint) external pure {} + function publicFunction(uint) public pure {} + function internalFunction(uint) internal pure {} +} + +contract C { + using {L.externalFunction} for uint; + using {L.publicFunction} for uint; + using {L.internalFunction} for uint; + + function f() public pure { + uint x; + x.externalFunction(); + x.publicFunction(); + x.internalFunction(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/using/library_inside_contract.sol b/test/libsolidity/syntaxTests/using/library_inside_contract.sol new file mode 100644 index 000000000..cd7f8fd19 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/library_inside_contract.sol @@ -0,0 +1,17 @@ +library L { + function externalFunction(uint) external pure {} + function publicFunction(uint) public pure {} + function internalFunction(uint) internal pure {} +} + +contract C { + using L for uint; + + function f() public pure { + uint x; + x.externalFunction(); + x.publicFunction(); + x.internalFunction(); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/using/library_non_free_external_function_err.sol b/test/libsolidity/syntaxTests/using/library_non_free_external_function_err.sol index 76d53cf90..0a51043db 100644 --- a/test/libsolidity/syntaxTests/using/library_non_free_external_function_err.sol +++ b/test/libsolidity/syntaxTests/using/library_non_free_external_function_err.sol @@ -11,4 +11,4 @@ contract C { } } // ---- -// DeclarationError 7920: (115-123): Identifier not found or not unique. +// TypeError 4357: (115-123): Library name expected. If you want to attach a function, use '{...}'. diff --git a/test/libsolidity/syntaxTests/using/module_identifier_not_found.sol b/test/libsolidity/syntaxTests/using/module_identifier_not_found.sol index ef1688b22..2526d216f 100644 --- a/test/libsolidity/syntaxTests/using/module_identifier_not_found.sol +++ b/test/libsolidity/syntaxTests/using/module_identifier_not_found.sol @@ -10,4 +10,4 @@ contract C { using { id } for uint; } // ---- -// DeclarationError 7920: (B:43-45): Identifier not found or not unique. +// DeclarationError 9589: (B:43-45): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/using/public_state_variable_getter.sol b/test/libsolidity/syntaxTests/using/public_state_variable_getter.sol new file mode 100644 index 000000000..9223a92a5 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/public_state_variable_getter.sol @@ -0,0 +1,11 @@ +contract A { + uint public data; +} + +contract C { + A a = new A(); + + using {a.data} for uint; +} +// ---- +// DeclarationError 9589: (82-88): Identifier is not a function name or not unique. diff --git a/test/libsolidity/syntaxTests/using/undeclared_library.sol b/test/libsolidity/syntaxTests/using/undeclared_library.sol new file mode 100644 index 000000000..c2174cc6c --- /dev/null +++ b/test/libsolidity/syntaxTests/using/undeclared_library.sol @@ -0,0 +1,3 @@ +using L for uint; +// ---- +// DeclarationError 9589: (6-7): Identifier is not a library name. diff --git a/test/libsolidity/syntaxTests/using/unqualified_library_functions_attached_in_single_directive_inside_library.sol b/test/libsolidity/syntaxTests/using/unqualified_library_functions_attached_in_single_directive_inside_library.sol new file mode 100644 index 000000000..7403dcf28 --- /dev/null +++ b/test/libsolidity/syntaxTests/using/unqualified_library_functions_attached_in_single_directive_inside_library.sol @@ -0,0 +1,19 @@ +library L { + function externalFunction(uint) external pure {} + function publicFunction(uint) public pure {} + function internalFunction(uint) internal pure {} + function privateFunction(uint) private pure {} + + using {externalFunction, publicFunction, internalFunction, privateFunction} for uint; + + function f() public pure { + uint x; + x.externalFunction(); + x.publicFunction(); + x.internalFunction(); + x.privateFunction(); + } +} +// ---- +// TypeError 6700: (365-385): Libraries cannot call their own functions externally. +// TypeError 6700: (395-413): Libraries cannot call their own functions externally.