Implement override checking

This commit is contained in:
Mathias Baumann
2019-10-30 17:31:33 +01:00
parent 5ff02c12e2
commit 6c6a9054b2
85 changed files with 965 additions and 204 deletions
@@ -1,4 +1,5 @@
contract B { function f() public {} }
contract C is B { function f() public view {} }
// ----
// TypeError: (56-83): Overriding function is missing 'override' specifier.
// TypeError: (56-83): Overriding function changes state mutability from "nonpayable" to "view".
@@ -6,8 +6,8 @@ contract A {
function i(uint[] calldata) external payable {}
}
contract B is A {
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 {}
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 {}
}
@@ -6,21 +6,17 @@ contract A {
function i(uint[] calldata) external payable {}
}
contract B is A {
function f(uint[] calldata) external pure {}
function g(uint[] calldata) external view { dummy; }
function h(uint[] calldata) external { dummy = 42; }
function i(uint[] calldata) external 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 {}
function f(uint[] calldata) external override pure {}
function g(uint[] calldata) external override view { dummy; }
function h(uint[] calldata) external override { dummy = 42; }
function i(uint[] calldata) external override payable {}
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 {}
}
// ----
// DeclarationError: (268-312): Function with same name and arguments defined twice.
// DeclarationError: (317-369): Function with same name and arguments defined twice.
// DeclarationError: (374-426): Function with same name and arguments defined twice.
// DeclarationError: (431-478): Function with same name and arguments defined twice.
// TypeError: (268-312): Overriding function visibility differs.
// TypeError: (317-369): Overriding function visibility differs.
// TypeError: (374-426): Overriding function visibility differs.
// TypeError: (431-478): Overriding function visibility differs.
// DeclarationError: (268-321): Function with same name and arguments defined twice.
// DeclarationError: (326-387): Function with same name and arguments defined twice.
// DeclarationError: (392-453): Function with same name and arguments defined twice.
// DeclarationError: (458-514): Function with same name and arguments defined twice.
@@ -6,8 +6,8 @@ interface I {
}
contract C is I {
uint dummy;
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 {}
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 {}
}
@@ -2,11 +2,11 @@ interface I {
function f(uint[] calldata) external pure;
}
contract A is I {
function f(uint[] memory) public pure {}
function f(uint[] memory) public override pure {}
}
contract C {
function f() public {
I i = I(new A());
i.f(new uint[](1));
}
}
}
@@ -8,10 +8,10 @@ interface I {
}
contract C is I {
uint dummy;
function f(S memory) public pure {}
function g(S memory) public view { dummy; }
function h(S memory) public { dummy = 42; }
function i(S memory) public payable {}
function f(S memory) public override pure {}
function g(S memory) public override view { dummy; }
function h(S memory) public override { dummy = 42; }
function i(S memory) public override payable {}
}
// ----
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
@@ -8,10 +8,10 @@ contract A {
function i(S calldata) external payable {}
}
contract B is A {
function f(S memory) public pure {}
function g(S memory) public view { dummy; }
function h(S memory) public { dummy = 42; }
function i(S memory) public payable {}
function f(S memory) public override pure {}
function g(S memory) public override view { dummy; }
function h(S memory) public override { dummy = 42; }
function i(S memory) public override payable {}
}
// ----
// Warning: (0-33): Experimental features are turned on. Do not use experimental features on live deployments.
@@ -7,4 +7,5 @@ contract B is I {
function f() public pure returns (uint, uint) {}
}
// ----
// TypeError: (182-230): Overriding function is missing 'override' specifier.
// TypeError: (182-230): Overriding function return types differ.
@@ -2,6 +2,6 @@ contract A {
function f() external pure {}
}
contract B is A {
function f() public pure {
function f() public override pure {
}
}
@@ -4,4 +4,3 @@ contract A {
}
// ----
// DeclarationError: (17-61): Function with same name and arguments defined twice.
// TypeError: (17-61): Overriding function visibility differs.
@@ -6,4 +6,4 @@ contract B {
}
contract C is A, B {}
// ----
// TypeError: (81-123): Overriding function visibility differs.
// TypeError: (126-147): Derived contract must override function "f". Function with the same name and parameter types defined in two or more base classes.
@@ -1,5 +1,11 @@
contract X {
contract A {
int public testvar;
function test() internal returns (uint256);
function test2() internal returns (uint256);
}
contract X is A {
int public override testvar;
function test() internal override returns (uint256);
function test2() internal override(A) returns (uint256);
}
// ----
@@ -0,0 +1,14 @@
contract A {
int public testvar;
function foo() internal returns (uint256);
}
contract B {
function foo() internal returns (uint256);
function test() internal returns (uint256);
}
contract X is A, B {
int public override testvar;
function test() internal override returns (uint256);
}
// ----
// TypeError: (184-290): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
@@ -0,0 +1,20 @@
contract A {
function foo() internal returns (uint256);
}
contract B is A {
function foo() internal override returns (uint256);
}
contract C is B {
function foo() internal override returns (uint256);
}
contract D is C {
function foo() internal override returns (uint256);
}
contract X is D {
function foo() internal override returns (uint256);
}
// ----
@@ -1,9 +1,21 @@
contract A {
int public testvar;
function foo() internal returns (uint256);
function test(uint8 _a) internal returns (uint256);
}
contract B {
function foo() internal returns (uint256);
function test() internal returns (uint256);
}
contract C {
function foo() internal returns (uint256);
}
contract X {
contract D {
function foo() internal returns (uint256);
}
contract X is A, B, C, D {
int public override testvar;
function test() internal override returns (uint256);
function foo() internal override(X, A) returns (uint256);
function foo() internal override(A, B, C, D) returns (uint256);
}
// ----
@@ -0,0 +1,15 @@
contract A {
int public testvar;
function foo() internal returns (uint256);
function test(uint8 _a) internal returns (uint256);
}
contract B {
function foo() internal returns (uint256);
}
contract C is A {
}
contract D is A, B, C {
function foo() internal override(A, B) returns (uint256);
}
// ----
@@ -0,0 +1,26 @@
contract A {
int public testvar;
function foo() internal returns (uint256);
function test(uint8 _a) internal returns (uint256);
}
contract B {
function foo() internal returns (uint256);
function test() internal returns (uint256);
}
contract C {
function foo() internal returns (uint256);
}
contract D {
function foo() internal returns (uint256);
function test() internal returns (uint256);
}
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);
}
// ----
// TypeError: (498-499): Duplicate contract "D" found in override list of "test".
// TypeError: (563-564): Duplicate contract "B" found in override list of "foo".
// TypeError: (566-567): Duplicate contract "B" found in override list of "foo".
// TypeError: (572-573): Duplicate contract "D" found in override list of "foo".
@@ -0,0 +1,24 @@
contract A {
int public testvar;
function foo() internal returns (uint256);
function test(uint8 _a) internal returns (uint256);
}
contract B {
function foo() internal returns (uint256);
function test() internal returns (uint256);
}
contract C {
function foo() internal returns (uint256);
}
contract D {
function foo() internal returns (uint256);
function test() internal returns (uint256);
}
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);
}
// ----
// TypeError: (483-500): Invalid contract specified in override list: C.
// TypeError: (545-559): Function needs to specify overridden contracts B and D.
@@ -0,0 +1,6 @@
contract A {
int public testvar;
function foo() internal override(N, Z) returns (uint256);
}
// ----
// DeclarationError: (68-69): Identifier not found or not unique.
@@ -0,0 +1,14 @@
contract A {
int public testvar;
function foo() internal returns (uint256);
}
contract B {
function foo() internal returns (uint8);
function test() internal returns (uint256);
}
contract X is A, B {
int public override testvar;
function test() internal override returns (uint256);
}
// ----
// TypeError: (182-288): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.
@@ -0,0 +1,15 @@
contract I {
function set() public {}
}
contract A is I {
uint a;
function set() public override { a = 1; super.set(); a = 2; }
}
contract B is I {
uint b;
function set() public override { b = 1; super.set(); b = 2; }
}
contract X is A, B {
function set() public override(A, B) { super.set(); }
}
@@ -0,0 +1,10 @@
contract I {
function f() external {}
}
contract A is I {
function f() external override {}
}
contract B is I {}
contract C is A, B {
function f() external override(A, I) {}
}
@@ -0,0 +1,6 @@
contract I {
function f() external {}
}
contract A is I {}
contract B is I {}
contract C is A, B {}
@@ -1,4 +1,5 @@
contract B { function f() public view {} }
contract C is B { function f() public {} }
// ----
// TypeError: (61-83): Overriding function is missing 'override' specifier.
// TypeError: (61-83): Overriding function changes state mutability from "view" to "nonpayable".
@@ -2,9 +2,9 @@ contract A {
function f() external pure {}
}
contract B is A {
function f() public pure {
function f() public override pure {
super.f();
}
}
// ----
// TypeError: (106-113): Member "f" not found or not visible after argument-dependent lookup in contract super B.
// TypeError: (115-122): Member "f" not found or not visible after argument-dependent lookup in contract super B.
@@ -1,4 +1,5 @@
contract A { modifier mod(uint a) { _; } }
contract B is A { modifier mod(uint8 a) { _; } }
// ----
// TypeError: (61-89): Overriding modifier is missing 'override' specifier.
// TypeError: (61-89): Override changes modifier signature.
@@ -2,4 +2,4 @@ contract A { modifier mod(uint a) { _; } }
contract B is A { function mod(uint a) public { } }
// ----
// DeclarationError: (61-92): Identifier already declared.
// TypeError: (13-40): Override changes modifier to function.
// TypeError: (61-92): Override changes modifier to function.
@@ -1,5 +1,6 @@
contract base { function foo() public; }
contract derived is base { function foo() public {} }
contract derived is base { function foo() public override {} }
contract wrong is derived { function foo() public; }
// ----
// TypeError: (123-145): Redeclaring an already implemented function as abstract
// TypeError: (132-154): Overriding function is missing 'override' specifier.
// TypeError: (132-154): Redeclaring an already implemented function as abstract
@@ -2,6 +2,7 @@ contract root { function rootFunction() public {} }
contract inter1 is root { function f() public {} }
contract inter2 is root { function f() public {} }
contract derived is root, inter2, inter1 {
function g() public { f(); rootFunction(); }
function g() public { f(); rootFunction(); }
function f() override(inter1, inter2) public {}
}
// ----
@@ -1,4 +1,5 @@
contract B { function f() internal {} }
contract C is B { function f() public {} }
// ----
// TypeError: (58-80): Overriding function is missing 'override' specifier.
// TypeError: (58-80): Overriding function visibility differs.
@@ -1,5 +1,5 @@
contract A { function f() public { uint8 x = C(0).g(); } }
contract B { function f() public {} function g() public returns (uint8) {} }
contract C is A, B { }
contract C is A, B { function f() public override (A, B) { A.f(); } }
// ----
// Warning: (35-42): Unused local variable.
@@ -3,5 +3,5 @@ contract A {
function() external { x = 1; }
}
contract C is A {
function() external { x = 2; }
function() override external { x = 2; }
}
@@ -2,7 +2,7 @@ contract Vehicle {
function f(bytes calldata) external returns (uint256 r) {r = 1;}
}
contract Bike is Vehicle {
function f(bytes calldata) external returns (uint256 r) {r = 42;}
function f(bytes calldata) override external returns (uint256 r) {r = 42;}
}
// ----
// Warning: (23-87): Function state mutability can be restricted to pure
@@ -2,7 +2,7 @@ contract base {
function f(uint a) public returns (uint) { }
}
contract test is base {
function f(uint a) public returns (uint8) { }
function f(uint a) public override returns (uint8) { }
}
// ----
// TypeError: (95-140): Overriding function return types differ.
// TypeError: (95-149): Overriding function return types differ.
@@ -4,4 +4,3 @@ contract C {
}
// ----
// DeclarationError: (17-66): Function with same name and arguments defined twice.
// TypeError: (17-66): Overriding function return types differ.
@@ -1,4 +1,5 @@
contract B { function f() payable public {} }
contract C is B { function f() public {} }
// ----
// TypeError: (64-86): Overriding function is missing 'override' specifier.
// TypeError: (64-86): Overriding function changes state mutability from "payable" to "nonpayable".
@@ -1,4 +1,5 @@
contract B { function f() public {} }
contract C is B { function f() payable public {} }
// ----
// TypeError: (56-86): Overriding function is missing 'override' specifier.
// TypeError: (56-86): Overriding function changes state mutability from "nonpayable" to "payable".
@@ -2,7 +2,7 @@ interface I {
function f() external;
}
contract C is I {
function f() public {
function f() public override {
}
}
// ----
@@ -5,7 +5,7 @@ interface I {
function() external;
}
contract C is I {
function f() public {
function f() public override {
}
}
// ----
@@ -2,6 +2,6 @@ interface I {
function f() external;
}
contract C is I {
function f() public {
function f() public override {
}
}
@@ -2,7 +2,7 @@ contract a {
function f() public;
}
contract b is a {
function f() public { super.f(); }
function f() public override { super.f(); }
}
// ----
// TypeError: (84-91): Member "f" not found or not visible after argument-dependent lookup in contract super b.
// TypeError: (93-100): Member "f" not found or not visible after argument-dependent lookup in contract super b.
@@ -2,11 +2,11 @@ contract a {
function f() public;
}
contract b is a {
function f() public { super.f(); }
function f() public override { super.f(); }
}
contract c is a,b {
// No error here.
function f() public { super.f(); }
function f() public override(a, b) { super.f(); }
}
// ----
// TypeError: (84-91): Member "f" not found or not visible after argument-dependent lookup in contract super b.
// TypeError: (93-100): Member "f" not found or not visible after argument-dependent lookup in contract super b.
@@ -2,5 +2,5 @@ interface D {
function f() view external;
}
contract C is D {
function f() view external {}
function f() override view external {}
}
@@ -4,13 +4,13 @@ contract D {
function g() public pure {}
}
contract C1 is D {
function f() public {}
function g() public view {}
function f() public override {}
function g() public override view {}
}
contract C2 is D {
function g() public {}
function g() public override {}
}
// ----
// TypeError: (118-140): Overriding function changes state mutability from "view" to "nonpayable".
// TypeError: (145-172): Overriding function changes state mutability from "pure" to "view".
// TypeError: (198-220): Overriding function changes state mutability from "pure" to "nonpayable".
// TypeError: (118-149): Overriding function changes state mutability from "view" to "nonpayable".
// TypeError: (154-190): Overriding function changes state mutability from "pure" to "view".
// TypeError: (216-247): Overriding function changes state mutability from "pure" to "nonpayable".
@@ -3,5 +3,5 @@ contract D {
function f() public { x = 2; }
}
contract C is D {
function f() public {}
function f() public override {}
}