Require unimplemented functions to be virtual.

This commit is contained in:
Daniel Kirchner
2019-12-02 21:59:00 +01:00
parent 958ec98cbe
commit 05baa23e8a
44 changed files with 123 additions and 118 deletions
@@ -1,4 +1,4 @@
abstract contract X { function test() internal returns (uint256); }
abstract contract X { function test() internal virtual returns (uint256); }
contract Y is X {
uint256 public test = 42;
}
@@ -6,4 +6,4 @@ contract T {
constructor() public { new Y(); }
}
// ----
// DeclarationError: (90-114): Identifier already declared.
// DeclarationError: (98-122): Identifier already declared.
@@ -1,4 +1,4 @@
abstract contract X { function test() private returns (uint256); }
abstract contract X { function test() private returns (uint256) {} }
contract Y is X {
uint256 public test = 42;
}
@@ -1,4 +1,4 @@
abstract contract X { function test() public returns (uint256); }
abstract contract X { function test() public virtual returns (uint256); }
contract Y is X {
uint256 public test = 42;
}
@@ -6,4 +6,4 @@ contract T {
constructor() public { new Y(); }
}
// ----
// DeclarationError: (88-112): Identifier already declared.
// DeclarationError: (96-120): Identifier already declared.
@@ -3,9 +3,9 @@ abstract contract A {
function test() internal virtual returns (uint256);
function test2() internal virtual returns (uint256);
}
abstract contract X is A {
contract X is A {
int public override testvar;
function test() internal override returns (uint256);
function test2() internal override(A) returns (uint256);
function test() internal override returns (uint256) {}
function test2() internal override(A) returns (uint256) {}
}
// ----
@@ -3,12 +3,12 @@ abstract contract A {
function foo() internal virtual returns (uint256);
}
abstract contract B {
function foo() internal returns (uint256);
function foo() internal virtual returns (uint256);
function test() internal virtual returns (uint256);
}
abstract contract X is A, B {
int public override testvar;
function test() internal override returns (uint256);
function test() internal override returns (uint256) {}
}
// ----
// TypeError: (218-333): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
// TypeError: (226-343): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
@@ -14,7 +14,7 @@ abstract contract D is C {
function foo() internal override virtual returns (uint256);
}
abstract contract X is D {
function foo() internal override returns (uint256);
contract X is D {
function foo() internal override returns (uint256) {}
}
// ----
@@ -2,8 +2,8 @@ interface A {
function test() external returns (uint256);
function test2() external returns (uint256);
}
abstract contract X is A {
function test() external override returns (uint256);
function test2() external override(A) returns (uint256);
contract X is A {
function test() external override returns (uint256) {}
function test2() external override(A) returns (uint256) {}
}
// ----
@@ -7,8 +7,8 @@ interface B {
function test() external returns (uint256);
function test2() external returns (uint256);
}
abstract contract X is A, B {
function test() external override(A, B) returns (uint256);
function test2() external override(B, A) returns (uint256);
contract X is A, B {
function test() external override(A, B) returns (uint256) {}
function test2() external override(B, A) returns (uint256) {}
}
// ----
@@ -1,11 +1,11 @@
abstract contract A {
function test() external virtual returns (uint256);
function test2() external returns (uint256);
function test2() external returns (uint256) {}
}
abstract contract X is A {
function test() external returns (uint256);
function test2() external override(A) returns (uint256);
function test() external returns (uint256) {}
function test2() external override(A) returns (uint256) {}
}
// ----
// TypeError: (151-194): Overriding function is missing 'override' specifier.
// TypeError: (76-120): Trying to override non-virtual function. Did you forget to add "virtual"?
// TypeError: (153-198): Overriding function is missing 'override' specifier.
// TypeError: (76-122): Trying to override non-virtual function. Did you forget to add "virtual"?
@@ -1,7 +1,7 @@
abstract contract A {
int public testvar;
function foo() internal virtual returns (uint256);
function test(uint8 _a) internal virtual returns (uint256);
function test(uint8 _a) internal virtual returns (uint256) {}
}
abstract contract B {
function foo() internal virtual returns (uint256);
@@ -13,9 +13,9 @@ abstract contract C {
abstract contract D {
function foo() internal virtual returns (uint256);
}
abstract contract X is A, B, C, D {
contract X is A, B, C, D {
int public override testvar;
function test() internal override returns (uint256);
function foo() internal override(A, B, C, D) returns (uint256);
function test() internal override returns (uint256) {}
function foo() internal override(A, B, C, D) returns (uint256) {}
}
// ----
@@ -1,7 +1,7 @@
abstract contract A {
int public testvar;
function foo() internal virtual returns (uint256);
function test(uint8 _a) internal returns (uint256);
function test(uint8 _a) internal virtual returns (uint256);
}
abstract contract B {
function foo() internal virtual returns (uint256);
@@ -10,6 +10,6 @@ abstract contract B {
abstract contract C is A {
}
abstract contract D is A, B, C {
function foo() internal override(A, B) returns (uint256);
function foo() internal override(A, B) virtual returns (uint256);
}
// ----
@@ -16,11 +16,11 @@ abstract contract D {
}
abstract contract X is A, B, C, D {
int public override testvar;
function test() internal override(B, D, D) returns (uint256);
function foo() internal override(A, C, B, B, B, D ,D) returns (uint256);
function test() internal override(B, D, D) virtual returns (uint256);
function foo() internal override(A, C, B, B, B, D ,D) virtual returns (uint256);
}
// ----
// TypeError: (599-600): Duplicate contract "D" found in override list of "test".
// TypeError: (664-665): Duplicate contract "B" found in override list of "foo".
// TypeError: (667-668): Duplicate contract "B" found in override list of "foo".
// TypeError: (673-674): Duplicate contract "D" found in override list of "foo".
// TypeError: (672-673): Duplicate contract "B" found in override list of "foo".
// TypeError: (675-676): Duplicate contract "B" found in override list of "foo".
// TypeError: (681-682): Duplicate contract "D" found in override list of "foo".
@@ -16,9 +16,9 @@ abstract contract D {
}
abstract contract X is A, B, C, D {
int public override testvar;
function test() internal override(B, D, C) returns (uint256);
function foo() internal override(A, C) returns (uint256);
function test() internal override(B, D, C) virtual returns (uint256);
function foo() internal override(A, C) virtual returns (uint256);
}
// ----
// TypeError: (584-601): Invalid contract specified in override list: C.
// TypeError: (646-660): Function needs to specify overridden contracts B and D.
// TypeError: (654-668): Function needs to specify overridden contracts B and D.
@@ -8,7 +8,7 @@ abstract contract B {
}
abstract contract X is A, B {
int public override testvar;
function test() internal override returns (uint256);
function test() internal override virtual returns (uint256);
}
// ----
// TypeError: (224-339): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
// TypeError: (224-347): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
@@ -18,9 +18,9 @@ abstract contract X is A, B, C, D {
enum ENUM { F,G,H }
int public override testvar;
function test() internal override returns (uint256);
function foo() internal override(MyStruct, ENUM, A, B, C, D) returns (uint256);
function test() internal override virtual returns (uint256);
function foo() internal override(MyStruct, ENUM, A, B, C, D) virtual returns (uint256);
}
// ----
// TypeError: (645-653): Expected contract but got struct X.MyStruct.
// TypeError: (655-659): Expected contract but got enum X.ENUM.
// TypeError: (653-661): Expected contract but got struct X.MyStruct.
// TypeError: (663-667): Expected contract but got enum X.ENUM.
@@ -2,8 +2,7 @@ contract A {
uint public x;
}
contract C is A {
function x() public returns (uint);
function x() public returns (uint) {}
}
// ----
// DeclarationError: (50-85): Identifier already declared.
// TypeError: (50-85): Redeclaring an already implemented function as abstract
// DeclarationError: (50-87): Identifier already declared.
@@ -2,7 +2,7 @@ abstract contract A {
function test() private virtual returns (uint256);
}
abstract contract X is A {
function test() private override returns (uint256);
function test() private override returns (uint256) {}
}
// ----
// TypeError: (23-73): "virtual" and "private" cannot be used together.
@@ -0,0 +1,5 @@
abstract contract C {
function f() external;
}
// ----
// TypeError: (23-45): Functions without implementation must be marked virtual.