From 6b37f1c02597d40dc3f70b2e17dc6a1bb3916e93 Mon Sep 17 00:00:00 2001 From: Mathias Baumann Date: Wed, 1 Jul 2020 16:21:52 +0200 Subject: [PATCH] Remove visiblity of libraries in inherited contracts. --- Changelog.md | 1 + docs/070-breaking-changes.rst | 1 + docs/contracts/libraries.rst | 5 ++--- libsolidity/ast/Types.cpp | 8 +++----- .../syntaxTests/scoping/library_inherited.sol | 17 +++++++++++++++++ .../syntaxTests/scoping/library_inherited2.sol | 16 ++++++++++++++++ 6 files changed, 40 insertions(+), 8 deletions(-) create mode 100644 test/libsolidity/syntaxTests/scoping/library_inherited.sol create mode 100644 test/libsolidity/syntaxTests/scoping/library_inherited2.sol diff --git a/Changelog.md b/Changelog.md index 6293fdc4e..817016258 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,7 @@ Breaking changes: * Type Checker: Exponentiation and shifts of literals by non-literals will always use ``uint256`` or ``int256`` as a type. * Type Checker: Disallow structs and arrays in memory or calldata if they contain nested mappings. * Type Checker: Disallow assignments to state variables that contain nested mappings. + * ``using A for B`` only affects the contract it is mentioned in and not all derived contracts * Inline Assembly: Disallow `.` in user-defined function and variable names. Language Features: diff --git a/docs/070-breaking-changes.rst b/docs/070-breaking-changes.rst index 31faef694..1c6ba132e 100644 --- a/docs/070-breaking-changes.rst +++ b/docs/070-breaking-changes.rst @@ -18,5 +18,6 @@ This section gives detailed instructions on how to update prior code for every b * Change ``now`` to ``block.timestamp``. * Change types of right operand in shift operators to unsigned types. For example change ``x >> (256 - y)`` to ``x >> uint(256 - y)``. +* Repeat the ``using A for B`` statements in all derived contracts if needed. * Remove the ``public`` keyword from every constructor. * Remove the ``internal`` keyword from every constructor and add ``abstract`` to the contract (if not already present). diff --git a/docs/contracts/libraries.rst b/docs/contracts/libraries.rst index 5a196e5dc..e28a16da2 100644 --- a/docs/contracts/libraries.rst +++ b/docs/contracts/libraries.rst @@ -30,9 +30,8 @@ not possible to destroy a library. Libraries can be seen as implicit base contracts of the contracts that use them. They will not be explicitly visible in the inheritance hierarchy, but calls to library functions look just like calls to functions of explicit base -contracts (``L.f()`` if ``L`` is the name of the library). Furthermore, -``internal`` functions of libraries are visible in all contracts, just as -if the library were a base contract. Of course, calls to internal functions +contracts (using qualified access like ``L.f()``). +Of course, calls to internal functions use the internal calling convention, which means that all internal types can be passed and types :ref:`stored in memory ` will be passed by reference and not copied. To realize this in the EVM, code of internal library functions diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index ff04e402f..6160238b6 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -355,11 +355,9 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc if (auto const* sourceUnit = dynamic_cast(&_scope)) usingForDirectives += ASTNode::filteredNodes(sourceUnit->nodes()); else if (auto const* contract = dynamic_cast(&_scope)) - { - for (ContractDefinition const* contract: contract->annotation().linearizedBaseContracts) - usingForDirectives += contract->usingForDirectives(); - usingForDirectives += ASTNode::filteredNodes(contract->sourceUnit().nodes()); - } + usingForDirectives += + contract->usingForDirectives() + + ASTNode::filteredNodes(contract->sourceUnit().nodes()); else solAssert(false, ""); diff --git a/test/libsolidity/syntaxTests/scoping/library_inherited.sol b/test/libsolidity/syntaxTests/scoping/library_inherited.sol new file mode 100644 index 000000000..60c16d7c4 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/library_inherited.sol @@ -0,0 +1,17 @@ +library Lib { + function foo(uint256 value) internal returns (uint256) { + return value + 42; + } +} + +contract A { + using Lib for uint256; +} + +contract B is A { + function bar(uint256 value) public returns (uint256) { + return value.foo(); // Usage of Lib + } +} +// ---- +// TypeError 9582: (246-255): Member "foo" not found or not visible after argument-dependent lookup in uint256. diff --git a/test/libsolidity/syntaxTests/scoping/library_inherited2.sol b/test/libsolidity/syntaxTests/scoping/library_inherited2.sol new file mode 100644 index 000000000..528ee05f3 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/library_inherited2.sol @@ -0,0 +1,16 @@ +library Lib { + function foo(uint256 value) internal pure returns (uint256) { + return value + 42; + } +} + +contract A { + using Lib for uint256; +} + +contract B is A { + using Lib for uint256; + function bar(uint256 value) public pure returns (uint256) { + return value.foo(); // Usage of Lib + } +}