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: 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:

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

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.
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 <data-location>` will be passed by reference and not copied.
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))
usingForDirectives += ASTNode::filteredNodes<UsingForDirective>(sourceUnit->nodes());
else if (auto const* contract = dynamic_cast<ContractDefinition const*>(&_scope))
{
for (ContractDefinition const* contract: contract->annotation().linearizedBaseContracts)
usingForDirectives += contract->usingForDirectives();
usingForDirectives += ASTNode::filteredNodes<UsingForDirective>(contract->sourceUnit().nodes());
}
usingForDirectives +=
contract->usingForDirectives() +
ASTNode::filteredNodes<UsingForDirective>(contract->sourceUnit().nodes());
else
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
}
}