mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add override exception for interface functions.
This commit is contained in:
parent
78afd71ab7
commit
f7916f2940
@ -1,6 +1,7 @@
|
||||
### 0.8.8 (unreleased)
|
||||
|
||||
Language Features:
|
||||
* Inheritance: A function that overrides only a single interface function does not require the ``override`` specifier.
|
||||
|
||||
|
||||
Compiler Features:
|
||||
|
@ -303,6 +303,13 @@ contracts can no longer change the behaviour of that function.
|
||||
outside of interfaces. In interfaces, all functions are
|
||||
automatically considered ``virtual``.
|
||||
|
||||
.. note::
|
||||
|
||||
Starting from Solidity 0.8.8, the ``override`` keyword is not
|
||||
required when overriding an interface function, except for the
|
||||
case where the function is defined in multiple bases.
|
||||
|
||||
|
||||
Public state variables can override external functions if the
|
||||
parameter and return types of the function matches the getter function
|
||||
of the variable:
|
||||
|
@ -33,10 +33,10 @@ Interfaces are denoted by their own keyword:
|
||||
|
||||
Contracts can inherit interfaces as they would inherit other contracts.
|
||||
|
||||
All functions declared in interfaces are implicitly ``virtual``, which means that
|
||||
they can be overridden. This does not automatically mean that an overriding function
|
||||
can be overridden again - this is only possible if the overriding
|
||||
function is marked ``virtual``.
|
||||
All functions declared in interfaces are implicitly ``virtual`` and any
|
||||
functions that override them do not need the ``override`` keyword.
|
||||
This does not automatically mean that an overriding function can be overridden again -
|
||||
this is only possible if the overriding function is marked ``virtual``.
|
||||
|
||||
Interfaces can inherit from other interfaces. This has the same rules as normal
|
||||
inheritance.
|
||||
|
@ -86,7 +86,8 @@ private:
|
||||
int currentNode = static_cast<int>(numNodes++);
|
||||
nodes[_function] = currentNode;
|
||||
nodeInv[currentNode] = _function;
|
||||
if (_function.overrides())
|
||||
|
||||
if (!_function.baseFunctions().empty())
|
||||
for (auto const& baseFunction: _function.baseFunctions())
|
||||
addEdge(currentNode, visit(baseFunction));
|
||||
else
|
||||
@ -518,7 +519,7 @@ void OverrideChecker::checkOverride(OverrideProxy const& _overriding, OverridePr
|
||||
"Override changes modifier signature."
|
||||
);
|
||||
|
||||
if (!_overriding.overrides())
|
||||
if (!_overriding.overrides() && !(_super.isFunction() && _super.contract().isInterface()))
|
||||
overrideError(
|
||||
_overriding,
|
||||
_super,
|
||||
|
@ -23,8 +23,6 @@ interface Sub is SuperA, SuperB {
|
||||
}
|
||||
|
||||
// ----
|
||||
// TypeError 9456: (572-616): Overriding function is missing "override" specifier.
|
||||
// TypeError 9456: (572-616): Overriding function is missing "override" specifier.
|
||||
// TypeError 4327: (572-616): Function needs to specify overridden contracts "SuperA" and "SuperB".
|
||||
// TypeError 4327: (647-655): Function needs to specify overridden contracts "SuperA" and "SuperB".
|
||||
// TypeError 4327: (705-721): Function needs to specify overridden contract "SuperB".
|
||||
|
@ -11,4 +11,3 @@ interface Sub is Super {
|
||||
}
|
||||
|
||||
// ----
|
||||
// TypeError 9456: (197-241): Overriding function is missing "override" specifier.
|
||||
|
@ -6,9 +6,9 @@ interface I {
|
||||
}
|
||||
contract C is I {
|
||||
uint dummy;
|
||||
function f(uint[] memory) public override pure {}
|
||||
function g(uint[] memory) public override view { dummy; }
|
||||
function h(uint[] memory) public override { dummy = 42; }
|
||||
function i(uint[] memory) public override payable {}
|
||||
function f(uint[] memory) public pure {}
|
||||
function g(uint[] memory) public view { dummy; }
|
||||
function h(uint[] memory) public { dummy = 42; }
|
||||
function i(uint[] memory) public payable {}
|
||||
}
|
||||
// ----
|
||||
|
@ -2,7 +2,7 @@ interface I {
|
||||
function f(uint[] calldata) external pure;
|
||||
}
|
||||
contract A is I {
|
||||
function f(uint[] memory) public override pure {}
|
||||
function f(uint[] memory) public pure {}
|
||||
}
|
||||
contract C {
|
||||
function f() public {
|
||||
|
@ -9,8 +9,8 @@ interface I {
|
||||
contract C is I {
|
||||
uint dummy;
|
||||
function f(S memory) public override pure {}
|
||||
function g(S memory) public override view { dummy; }
|
||||
function g(S memory) public view { dummy; }
|
||||
function h(S memory) public override { dummy = 42; }
|
||||
function i(S memory) public override payable {}
|
||||
function i(S memory) public payable {}
|
||||
}
|
||||
// ----
|
||||
|
@ -7,5 +7,4 @@ contract B is I {
|
||||
function f() public pure returns (uint, uint) {}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9456: (182-230): Overriding function is missing "override" specifier.
|
||||
// TypeError 4822: (182-230): Overriding function return types differ.
|
||||
|
@ -3,15 +3,15 @@ interface I {
|
||||
function g() external;
|
||||
}
|
||||
abstract contract A is I {
|
||||
function f() external override {}
|
||||
function g() external override virtual;
|
||||
function f() external {}
|
||||
function g() external virtual;
|
||||
}
|
||||
abstract contract B is I {
|
||||
function g() external override {}
|
||||
function f() external override virtual;
|
||||
function g() external {}
|
||||
function f() external virtual;
|
||||
}
|
||||
contract C is A, B {
|
||||
}
|
||||
// ----
|
||||
// TypeError 6480: (292-314): Derived contract must override function "f". Two or more base classes define function with same name and parameter types.
|
||||
// TypeError 6480: (292-314): Derived contract must override function "g". Two or more base classes define function with same name and parameter types.
|
||||
// TypeError 6480: (256-278): Derived contract must override function "f". Two or more base classes define function with same name and parameter types.
|
||||
// TypeError 6480: (256-278): Derived contract must override function "g". Two or more base classes define function with same name and parameter types.
|
||||
|
@ -3,10 +3,10 @@ interface I {
|
||||
function g() external;
|
||||
}
|
||||
abstract contract A is I {
|
||||
function f() external override {}
|
||||
function f() external {}
|
||||
}
|
||||
abstract contract B is I {
|
||||
function g() external override {}
|
||||
function g() external {}
|
||||
}
|
||||
contract C is A, B {
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ interface I {
|
||||
}
|
||||
abstract contract A is I
|
||||
{
|
||||
uint public override f;
|
||||
uint public f;
|
||||
}
|
||||
abstract contract B is I
|
||||
{
|
||||
|
@ -3,12 +3,12 @@ interface I {
|
||||
}
|
||||
contract A is I
|
||||
{
|
||||
uint public override f;
|
||||
uint public f;
|
||||
}
|
||||
abstract contract B is I
|
||||
{
|
||||
function f() external virtual override returns (uint);
|
||||
function f() external virtual returns (uint);
|
||||
}
|
||||
abstract contract C is A, B {}
|
||||
// ----
|
||||
// TypeError 6480: (185-215): Derived contract must override function "f". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.
|
||||
// TypeError 6480: (167-197): Derived contract must override function "f". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.
|
||||
|
@ -3,12 +3,12 @@ interface I {
|
||||
}
|
||||
contract A is I
|
||||
{
|
||||
uint public override f;
|
||||
uint public f;
|
||||
}
|
||||
abstract contract B is I
|
||||
{
|
||||
function f() external virtual override returns (uint) { return 2; }
|
||||
function f() external virtual returns (uint) { return 2; }
|
||||
}
|
||||
abstract contract C is A, B {}
|
||||
// ----
|
||||
// TypeError 6480: (198-228): Derived contract must override function "f". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.
|
||||
// TypeError 6480: (180-210): Derived contract must override function "f". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.
|
||||
|
@ -1,3 +1,3 @@
|
||||
interface ERC20 { function x() external returns (uint); }
|
||||
contract C is ERC20 { uint public override x; }
|
||||
contract C is ERC20 { uint public x; }
|
||||
// ----
|
||||
|
@ -1,6 +1,6 @@
|
||||
interface X { function test() external returns (uint256); }
|
||||
contract Y is X {
|
||||
uint256 public override test = 42;
|
||||
uint256 public test = 42;
|
||||
}
|
||||
contract T {
|
||||
constructor() { new Y(); }
|
||||
|
@ -0,0 +1,8 @@
|
||||
abstract contract I {
|
||||
function f() external virtual;
|
||||
}
|
||||
contract C is I {
|
||||
function f() external {}
|
||||
}
|
||||
// ----
|
||||
// TypeError 9456: (75-99): Overriding function is missing "override" specifier.
|
@ -0,0 +1,19 @@
|
||||
interface I {
|
||||
function f() external;
|
||||
function g() external;
|
||||
function h() external;
|
||||
}
|
||||
interface J {
|
||||
function f() external;
|
||||
function g() external;
|
||||
function h() external;
|
||||
}
|
||||
contract C is I, J {
|
||||
function f() external {}
|
||||
function g() external override {}
|
||||
function h() external override(I) {}
|
||||
}
|
||||
// ----
|
||||
// TypeError 4327: (198-222): Function needs to specify overridden contracts "I" and "J".
|
||||
// TypeError 4327: (246-254): Function needs to specify overridden contracts "I" and "J".
|
||||
// TypeError 4327: (281-292): Function needs to specify overridden contract "J".
|
@ -0,0 +1,11 @@
|
||||
interface I {
|
||||
function f() external;
|
||||
function g() external;
|
||||
function h() external;
|
||||
}
|
||||
contract C is I {
|
||||
function f() external {}
|
||||
function g() external override {}
|
||||
function h() external override(I) {}
|
||||
}
|
||||
// ----
|
@ -1,9 +1,11 @@
|
||||
interface A {
|
||||
function test() external returns (uint256);
|
||||
function test2() external returns (uint256);
|
||||
function test3() external returns (uint256);
|
||||
}
|
||||
contract X is A {
|
||||
function test() external override returns (uint256) {}
|
||||
function test2() external override(A) returns (uint256) {}
|
||||
function test3() external returns (uint256) {}
|
||||
}
|
||||
// ----
|
||||
|
@ -11,11 +11,11 @@ contract X is A, B {
|
||||
function goo() external virtual override(A, B) returns (uint) {}
|
||||
}
|
||||
abstract contract T is A {
|
||||
function foo() external virtual override returns (uint);
|
||||
function goo() external virtual override returns (uint);
|
||||
function foo() external virtual returns (uint);
|
||||
function goo() external virtual returns (uint);
|
||||
}
|
||||
contract Y is X, T {
|
||||
}
|
||||
// ----
|
||||
// TypeError 6480: (484-506): Derived contract must override function "foo". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.
|
||||
// TypeError 6480: (484-506): Derived contract must override function "goo". Two or more base classes define function with same name and parameter types.
|
||||
// TypeError 6480: (466-488): Derived contract must override function "foo". Two or more base classes define function with same name and parameter types. Since one of the bases defines a public state variable which cannot be overridden, you have to change the inheritance layout or the names of the functions.
|
||||
// TypeError 6480: (466-488): Derived contract must override function "goo". Two or more base classes define function with same name and parameter types.
|
||||
|
Loading…
Reference in New Issue
Block a user