Remove visiblity of libraries in inherited contracts.

This commit is contained in:
Mathias Baumann 2020-07-01 16:21:52 +02:00 committed by chriseth
parent 9ef050af9a
commit 6b37f1c025
6 changed files with 40 additions and 8 deletions

View File

@ -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: 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 structs and arrays in memory or calldata if they contain nested mappings.
* Type Checker: Disallow assignments to state variables that 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. * Inline Assembly: Disallow `.` in user-defined function and variable names.
Language Features: Language Features:

View File

@ -18,5 +18,6 @@ This section gives detailed instructions on how to update prior code for every b
* Change ``now`` to ``block.timestamp``. * Change ``now`` to ``block.timestamp``.
* Change types of right operand in shift operators to unsigned types. For example change ``x >> (256 - y)`` to * Change types of right operand in shift operators to unsigned types. For example change ``x >> (256 - y)`` to
``x >> uint(256 - y)``. ``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 ``public`` keyword from every constructor.
* Remove the ``internal`` keyword from every constructor and add ``abstract`` to the contract (if not already present). * Remove the ``internal`` keyword from every constructor and add ``abstract`` to the contract (if not already present).

View File

@ -30,9 +30,8 @@ not possible to destroy a library.
Libraries can be seen as implicit base contracts of the contracts that use them. 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 They will not be explicitly visible in the inheritance hierarchy, but calls
to library functions look just like calls to functions of explicit base to library functions look just like calls to functions of explicit base
contracts (``L.f()`` if ``L`` is the name of the library). Furthermore, contracts (using qualified access like ``L.f()``).
``internal`` functions of libraries are visible in all contracts, just as Of course, calls to internal functions
if the library were a base contract. Of course, calls to internal functions
use the internal calling convention, which means that all internal types use the internal calling convention, which means that all internal types
can be passed and types :ref:`stored in memory <data-location>` will be passed by reference and not copied. can be passed and types :ref:`stored in memory <data-location>` will be passed by reference and not copied.
To realize this in the EVM, code of internal library functions To realize this in the EVM, code of internal library functions

View File

@ -355,11 +355,9 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ASTNode const& _sc
if (auto const* sourceUnit = dynamic_cast<SourceUnit const*>(&_scope)) if (auto const* sourceUnit = dynamic_cast<SourceUnit const*>(&_scope))
usingForDirectives += ASTNode::filteredNodes<UsingForDirective>(sourceUnit->nodes()); usingForDirectives += ASTNode::filteredNodes<UsingForDirective>(sourceUnit->nodes());
else if (auto const* contract = dynamic_cast<ContractDefinition const*>(&_scope)) else if (auto const* contract = dynamic_cast<ContractDefinition const*>(&_scope))
{ usingForDirectives +=
for (ContractDefinition const* contract: contract->annotation().linearizedBaseContracts) contract->usingForDirectives() +
usingForDirectives += contract->usingForDirectives(); ASTNode::filteredNodes<UsingForDirective>(contract->sourceUnit().nodes());
usingForDirectives += ASTNode::filteredNodes<UsingForDirective>(contract->sourceUnit().nodes());
}
else else
solAssert(false, ""); solAssert(false, "");

View File

@ -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.

View File

@ -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
}
}