Merge pull request #7870 from ethereum/unimplementedRequireVirtual

Require virtual for unimplemented functions.
This commit is contained in:
chriseth 2019-12-03 11:21:38 +01:00 committed by GitHub
commit b5d3b95307
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 131 additions and 126 deletions

View File

@ -529,11 +529,11 @@ As an example, the code
pragma experimental ABIEncoderV2; pragma experimental ABIEncoderV2;
abstract contract Test { contract Test {
struct S { uint a; uint[] b; T[] c; } struct S { uint a; uint[] b; T[] c; }
struct T { uint x; uint y; } struct T { uint x; uint y; }
function f(S memory s, T memory t, uint a) public; function f(S memory s, T memory t, uint a) public {}
function g() public returns (S memory s, T memory t, uint a); function g() public returns (S memory s, T memory t, uint a) {}
} }
would result in the JSON: would result in the JSON:

View File

@ -15,7 +15,7 @@ provided (no implementation body ``{ }`` was given).::
pragma solidity >=0.4.0 <0.7.0; pragma solidity >=0.4.0 <0.7.0;
abstract contract Feline { abstract contract Feline {
function utterance() public returns (bytes32); function utterance() public virtual returns (bytes32);
} }
Such abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement Such abstract contracts can not be instantiated directly. This is also true, if an abstract contract itself does implement

View File

@ -53,13 +53,13 @@ Details are given in the following example.
// without body. If a contract does not implement all // without body. If a contract does not implement all
// functions it can only be used as an interface. // functions it can only be used as an interface.
abstract contract Config { abstract contract Config {
function lookup(uint id) public returns (address adr); function lookup(uint id) public virtual returns (address adr);
} }
abstract contract NameReg { abstract contract NameReg {
function register(bytes32 name) public; function register(bytes32 name) public virtual;
function unregister() public; function unregister() public virtual;
} }

View File

@ -433,6 +433,8 @@ bool TypeChecker::visit(FunctionDefinition const& _function)
m_errorReporter.typeError(_function.location(), "Constructor must be implemented if declared."); m_errorReporter.typeError(_function.location(), "Constructor must be implemented if declared.");
else if (isLibraryFunction) else if (isLibraryFunction)
m_errorReporter.typeError(_function.location(), "Library functions must be implemented if declared."); m_errorReporter.typeError(_function.location(), "Library functions must be implemented if declared.");
else if (!_function.virtualSemantics())
m_errorReporter.typeError(_function.location(), "Functions without implementation must be marked virtual.");
if (_function.isFallback()) if (_function.isFallback())

View File

@ -87,7 +87,7 @@ virtual returns (bool success);
} }
abstract contract tokenRecipient { abstract contract tokenRecipient {
function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData) public; function receiveApproval(address _from, uint256 _value, address _token, bytes memory _extraData) public virtual;
} }
contract Token is TokenInterface { contract Token is TokenInterface {

View File

@ -10464,7 +10464,7 @@ BOOST_AUTO_TEST_CASE(mutex)
BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws) BOOST_AUTO_TEST_CASE(calling_nonexisting_contract_throws)
{ {
char const* sourceCode = R"YY( char const* sourceCode = R"YY(
abstract contract D { function g() public; } abstract contract D { function g() public virtual; }
contract C { contract C {
D d = D(0x1212); D d = D(0x1212);
function f() public returns (uint) { function f() public returns (uint) {

View File

@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(function_no_implementation)
SourceUnit const* sourceUnit = nullptr; SourceUnit const* sourceUnit = nullptr;
char const* text = R"( char const* text = R"(
abstract contract test { abstract contract test {
function functionName(bytes32 input) public returns (bytes32 out); function functionName(bytes32 input) public virtual returns (bytes32 out);
} }
)"; )";
sourceUnit = parseAndAnalyse(text); sourceUnit = parseAndAnalyse(text);
@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(abstract_contract_with_overload)
{ {
SourceUnit const* sourceUnit = nullptr; SourceUnit const* sourceUnit = nullptr;
char const* text = R"( char const* text = R"(
abstract contract base { function foo(bool) public; } abstract contract base { function foo(bool) public virtual; }
abstract contract derived is base { function foo(uint) public {} } abstract contract derived is base { function foo(uint) public {} }
)"; )";
sourceUnit = parseAndAnalyse(text); sourceUnit = parseAndAnalyse(text);
@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE(implement_abstract_via_constructor)
{ {
SourceUnit const* sourceUnit = nullptr; SourceUnit const* sourceUnit = nullptr;
char const* text = R"( char const* text = R"(
abstract contract base { function foo() public; } abstract contract base { function foo() public virtual; }
abstract contract foo is base { constructor() public {} } abstract contract foo is base { constructor() public {} }
)"; )";
sourceUnit = parseAndAnalyse(text); sourceUnit = parseAndAnalyse(text);
@ -357,7 +357,7 @@ BOOST_AUTO_TEST_CASE(dynamic_return_types_not_possible)
{ {
char const* sourceCode = R"( char const* sourceCode = R"(
abstract contract C { abstract contract C {
function f(uint) public returns (string memory); function f(uint) public virtual returns (string memory);
function g() public { function g() public {
string memory x = this.f(2); string memory x = this.f(2);
// we can assign to x but it is not usable. // we can assign to x but it is not usable.

View File

@ -2,7 +2,7 @@ pragma experimental SMTChecker;
abstract contract D abstract contract D
{ {
function g(uint x) public; function g(uint x) public virtual;
} }
contract C contract C
@ -17,4 +17,4 @@ contract C
} }
} }
// ---- // ----
// Warning: (249-263): Assertion violation happens here // Warning: (257-271): Assertion violation happens here

View File

@ -2,7 +2,7 @@ pragma experimental SMTChecker;
abstract contract D abstract contract D
{ {
function g(uint x) public; function g(uint x) public virtual;
} }
contract C contract C
@ -17,4 +17,4 @@ contract C
} }
} }
// ---- // ----
// Warning: (289-313): Assertion violation happens here // Warning: (297-321): Assertion violation happens here

View File

@ -2,7 +2,7 @@ pragma experimental SMTChecker;
abstract contract D abstract contract D
{ {
function g(uint x) public; function g(uint x) public virtual;
} }
contract C contract C
@ -18,4 +18,4 @@ contract C
} }
} }
// ---- // ----
// Warning: (347-371): Assertion violation happens here // Warning: (355-379): Assertion violation happens here

View File

@ -1,5 +1,5 @@
contract A { contract A {
function a() public; function a() public virtual;
} }
// ---- // ----
// TypeError: (0-39): Contract "A" should be marked as abstract. // TypeError: (0-47): Contract "A" should be marked as abstract.

View File

@ -1,7 +1,7 @@
abstract contract A { abstract contract A {
function a() public; function a() public virtual;
} }
contract B is A { contract B is A {
} }
// ---- // ----
// TypeError: (49-68): Contract "B" should be marked as abstract. // TypeError: (57-76): Contract "B" should be marked as abstract.

View File

@ -1,5 +1,5 @@
abstract contract C { abstract contract C {
function f() internal returns(uint[] storage); function f() internal virtual returns(uint[] storage);
function g() internal returns(uint[] storage s); function g() internal virtual returns(uint[] storage s);
} }
// ---- // ----

View File

@ -1,4 +1,4 @@
abstract contract test { contract test {
function f(bytes calldata) external; function f(bytes calldata) external {}
} }
// ---- // ----

View File

@ -1,4 +1,4 @@
abstract contract test { contract test {
function f(bytes memory) internal; function f(bytes memory) internal {}
} }
// ---- // ----

View File

@ -1,4 +1,4 @@
abstract contract test { contract test {
function f(bytes storage) internal; function f(bytes storage) internal {}
} }
// ---- // ----

View File

@ -1,4 +1,4 @@
abstract contract test { contract test {
function f(bytes memory) public; function f(bytes memory) public {}
} }
// ---- // ----

View File

@ -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 { contract Y is X {
uint256 public test = 42; uint256 public test = 42;
} }
@ -6,4 +6,4 @@ contract T {
constructor() public { new Y(); } constructor() public { new Y(); }
} }
// ---- // ----
// DeclarationError: (90-114): Identifier already declared. // DeclarationError: (98-122): Identifier already declared.

View File

@ -1,4 +1,4 @@
abstract contract X { function test() private returns (uint256); } abstract contract X { function test() private returns (uint256) {} }
contract Y is X { contract Y is X {
uint256 public test = 42; uint256 public test = 42;
} }

View File

@ -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 { contract Y is X {
uint256 public test = 42; uint256 public test = 42;
} }
@ -6,4 +6,4 @@ contract T {
constructor() public { new Y(); } constructor() public { new Y(); }
} }
// ---- // ----
// DeclarationError: (88-112): Identifier already declared. // DeclarationError: (96-120): Identifier already declared.

View File

@ -3,9 +3,9 @@ abstract contract A {
function test() internal virtual returns (uint256); function test() internal virtual returns (uint256);
function test2() internal virtual returns (uint256); function test2() internal virtual returns (uint256);
} }
abstract contract X is A { contract X is A {
int public override testvar; int public override testvar;
function test() internal override returns (uint256); function test() internal override returns (uint256) {}
function test2() internal override(A) returns (uint256); function test2() internal override(A) returns (uint256) {}
} }
// ---- // ----

View File

@ -3,12 +3,12 @@ abstract contract A {
function foo() internal virtual returns (uint256); function foo() internal virtual returns (uint256);
} }
abstract contract B { abstract contract B {
function foo() internal returns (uint256); function foo() internal virtual returns (uint256);
function test() internal virtual returns (uint256); function test() internal virtual returns (uint256);
} }
abstract contract X is A, B { abstract contract X is A, B {
int public override testvar; 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.

View File

@ -14,7 +14,7 @@ abstract contract D is C {
function foo() internal override virtual returns (uint256); function foo() internal override virtual returns (uint256);
} }
abstract contract X is D { contract X is D {
function foo() internal override returns (uint256); function foo() internal override returns (uint256) {}
} }
// ---- // ----

View File

@ -2,8 +2,8 @@ interface A {
function test() external returns (uint256); function test() external returns (uint256);
function test2() external returns (uint256); function test2() external returns (uint256);
} }
abstract contract X is A { contract X is A {
function test() external override returns (uint256); function test() external override returns (uint256) {}
function test2() external override(A) returns (uint256); function test2() external override(A) returns (uint256) {}
} }
// ---- // ----

View File

@ -7,8 +7,8 @@ interface B {
function test() external returns (uint256); function test() external returns (uint256);
function test2() external returns (uint256); function test2() external returns (uint256);
} }
abstract contract X is A, B { contract X is A, B {
function test() external override(A, B) returns (uint256); function test() external override(A, B) returns (uint256) {}
function test2() external override(B, A) returns (uint256); function test2() external override(B, A) returns (uint256) {}
} }
// ---- // ----

View File

@ -1,11 +1,11 @@
abstract contract A { abstract contract A {
function test() external virtual returns (uint256); function test() external virtual returns (uint256);
function test2() external returns (uint256); function test2() external returns (uint256) {}
} }
abstract contract X is A { abstract contract X is A {
function test() external returns (uint256); function test() external returns (uint256) {}
function test2() external override(A) returns (uint256); function test2() external override(A) returns (uint256) {}
} }
// ---- // ----
// TypeError: (151-194): Overriding function is missing 'override' specifier. // TypeError: (153-198): Overriding function is missing 'override' specifier.
// TypeError: (76-120): Trying to override non-virtual function. Did you forget to add "virtual"? // TypeError: (76-122): Trying to override non-virtual function. Did you forget to add "virtual"?

View File

@ -1,7 +1,7 @@
abstract contract A { abstract contract A {
int public testvar; int public testvar;
function foo() internal virtual returns (uint256); 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 { abstract contract B {
function foo() internal virtual returns (uint256); function foo() internal virtual returns (uint256);
@ -13,9 +13,9 @@ abstract contract C {
abstract contract D { abstract contract D {
function foo() internal virtual returns (uint256); 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; int public override testvar;
function test() internal override returns (uint256); function test() internal override returns (uint256) {}
function foo() internal override(A, B, C, D) returns (uint256); function foo() internal override(A, B, C, D) returns (uint256) {}
} }
// ---- // ----

View File

@ -1,7 +1,7 @@
abstract contract A { abstract contract A {
int public testvar; int public testvar;
function foo() internal virtual returns (uint256); function foo() internal virtual returns (uint256);
function test(uint8 _a) internal returns (uint256); function test(uint8 _a) internal virtual returns (uint256);
} }
abstract contract B { abstract contract B {
function foo() internal virtual returns (uint256); function foo() internal virtual returns (uint256);
@ -10,6 +10,6 @@ abstract contract B {
abstract contract C is A { abstract contract C is A {
} }
abstract contract D is A, B, C { abstract contract D is A, B, C {
function foo() internal override(A, B) returns (uint256); function foo() internal override(A, B) virtual returns (uint256);
} }
// ---- // ----

View File

@ -16,11 +16,11 @@ abstract contract D {
} }
abstract contract X is A, B, C, D { abstract contract X is A, B, C, D {
int public override testvar; int public override testvar;
function test() internal override(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) 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: (599-600): Duplicate contract "D" found in override list of "test".
// TypeError: (664-665): Duplicate contract "B" found in override list of "foo". // TypeError: (672-673): Duplicate contract "B" found in override list of "foo".
// TypeError: (667-668): Duplicate contract "B" found in override list of "foo". // TypeError: (675-676): Duplicate contract "B" found in override list of "foo".
// TypeError: (673-674): Duplicate contract "D" found in override list of "foo". // TypeError: (681-682): Duplicate contract "D" found in override list of "foo".

View File

@ -16,9 +16,9 @@ abstract contract D {
} }
abstract contract X is A, B, C, D { abstract contract X is A, B, C, D {
int public override testvar; int public override testvar;
function test() internal override(B, D, C) returns (uint256); function test() internal override(B, D, C) virtual returns (uint256);
function foo() internal override(A, C) returns (uint256); function foo() internal override(A, C) virtual returns (uint256);
} }
// ---- // ----
// TypeError: (584-601): Invalid contract specified in override list: C. // 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.

View File

@ -8,7 +8,7 @@ abstract contract B {
} }
abstract contract X is A, B { abstract contract X is A, B {
int public override testvar; 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.

View File

@ -18,9 +18,9 @@ abstract contract X is A, B, C, D {
enum ENUM { F,G,H } enum ENUM { F,G,H }
int public override testvar; int public override testvar;
function test() internal override returns (uint256); function test() internal override virtual returns (uint256);
function foo() internal override(MyStruct, ENUM, A, B, C, D) 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: (653-661): Expected contract but got struct X.MyStruct.
// TypeError: (655-659): Expected contract but got enum X.ENUM. // TypeError: (663-667): Expected contract but got enum X.ENUM.

View File

@ -2,8 +2,7 @@ contract A {
uint public x; uint public x;
} }
contract C is A { contract C is A {
function x() public returns (uint); function x() public returns (uint) {}
} }
// ---- // ----
// DeclarationError: (50-85): Identifier already declared. // DeclarationError: (50-87): Identifier already declared.
// TypeError: (50-85): Redeclaring an already implemented function as abstract

View File

@ -2,7 +2,7 @@ abstract contract A {
function test() private virtual returns (uint256); function test() private virtual returns (uint256);
} }
abstract contract X is A { 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. // TypeError: (23-73): "virtual" and "private" cannot be used together.

View File

@ -0,0 +1,5 @@
abstract contract C {
function f() external;
}
// ----
// TypeError: (23-45): Functions without implementation must be marked virtual.

View File

@ -5,9 +5,9 @@
abstract contract C abstract contract C
{ {
modifier only_owner() { _; } modifier only_owner() { _; }
function foo() only_owner public; function foo() only_owner public virtual;
function bar() public only_owner; function bar() public only_owner virtual;
} }
// ---- // ----
// SyntaxError: (212-245): Functions without implementation cannot have modifiers. // SyntaxError: (212-253): Functions without implementation cannot have modifiers.
// SyntaxError: (250-283): Functions without implementation cannot have modifiers. // SyntaxError: (258-299): Functions without implementation cannot have modifiers.

View File

@ -1,4 +1,4 @@
abstract contract C { contract C {
function f() public { function f() public {
uint a = two(); uint a = two();
uint b = three(); uint b = three();
@ -13,17 +13,17 @@ abstract contract C {
(uint a1, uint b1, uint c1, uint d1) = three(); (uint a1, uint b1, uint c1, uint d1) = three();
(uint a2, uint b2, uint c2) = four(); (uint a2, uint b2, uint c2) = four();
} }
function one() public pure returns (uint); function one() public pure returns (uint) {}
function two() public pure returns (uint, uint); function two() public pure returns (uint, uint) {}
function three() public pure returns (uint, uint, uint); function three() public pure returns (uint, uint, uint) {}
function four() public pure returns (uint, uint, uint, uint); function four() public pure returns (uint, uint, uint, uint) {}
} }
// ---- // ----
// TypeError: (56-70): Different number of components on the left hand side (1) than on the right hand side (2). // TypeError: (47-61): Different number of components on the left hand side (1) than on the right hand side (2).
// TypeError: (80-96): Different number of components on the left hand side (1) than on the right hand side (3). // TypeError: (71-87): Different number of components on the left hand side (1) than on the right hand side (3).
// TypeError: (106-121): Different number of components on the left hand side (1) than on the right hand side (4). // TypeError: (97-112): Different number of components on the left hand side (1) than on the right hand side (4).
// TypeError: (163-207): Different number of components on the left hand side (4) than on the right hand side (1). // TypeError: (154-198): Different number of components on the left hand side (4) than on the right hand side (1).
// TypeError: (217-252): Different number of components on the left hand side (3) than on the right hand side (1). // TypeError: (208-243): Different number of components on the left hand side (3) than on the right hand side (1).
// TypeError: (262-288): Different number of components on the left hand side (2) than on the right hand side (1). // TypeError: (253-279): Different number of components on the left hand side (2) than on the right hand side (1).
// TypeError: (330-376): Different number of components on the left hand side (4) than on the right hand side (3). // TypeError: (321-367): Different number of components on the left hand side (4) than on the right hand side (3).
// TypeError: (386-422): Different number of components on the left hand side (3) than on the right hand side (4). // TypeError: (377-413): Different number of components on the left hand side (3) than on the right hand side (4).

View File

@ -12,11 +12,11 @@ abstract contract C {
(,uint m, uint n,) = five(); (,uint m, uint n,) = five();
a;b;c;d;e;f;g;h;i;j;k;l;m;n; a;b;c;d;e;f;g;h;i;j;k;l;m;n;
} }
function one() public pure returns (uint); function one() public pure returns (uint) {}
function two() public pure returns (uint, uint); function two() public pure returns (uint, uint) {}
function three() public pure returns (uint, uint, uint); function three() public pure returns (uint, uint, uint) {}
function four() public pure returns (uint, uint, uint, uint); function four() public pure returns (uint, uint, uint, uint) {}
function five() public pure returns (uint, uint, uint, uint, uint); function five() public pure returns (uint, uint, uint, uint, uint) {}
} }
// ---- // ----
// TypeError: (62-81): Different number of components on the left hand side (2) than on the right hand side (3). // TypeError: (62-81): Different number of components on the left hand side (2) than on the right hand side (3).

View File

@ -1,7 +1,7 @@
contract base { function foo() public; } contract base { function foo() public virtual; }
contract derived { contract derived {
base b; base b;
function foo() public { b = new base(); } function foo() public { b = new base(); }
} }
// ---- // ----
// TypeError: (0-40): Contract "base" should be marked as abstract. // TypeError: (0-48): Contract "base" should be marked as abstract.

View File

@ -1,6 +1,5 @@
abstract contract base { function foo() public virtual; } abstract contract base { function foo() public virtual; }
contract derived is base { function foo() public virtual override {} } contract derived is base { function foo() public virtual override {} }
contract wrong is derived { function foo() public; } contract wrong is derived { function foo() public virtual override; }
// ---- // ----
// TypeError: (157-179): Overriding function is missing 'override' specifier. // TypeError: (157-196): Redeclaring an already implemented function as abstract
// TypeError: (157-179): Redeclaring an already implemented function as abstract

View File

@ -1,5 +1,5 @@
abstract contract M { abstract contract M {
function f(uint[] memory) public; function f(uint[] memory) public virtual;
function f(int[] memory) public; function f(int[] memory) public virtual;
} }
// ---- // ----

View File

@ -1,4 +1,4 @@
abstract contract C { abstract contract C {
function f(uint a) pure public returns (uint b); function f(uint a) pure public virtual returns (uint b);
} }
// ---- // ----

View File

@ -1,5 +1,5 @@
abstract contract C { abstract contract C {
function transfer(uint) public; function transfer(uint) public virtual;
function f() public { function f() public {
this.transfer(10); this.transfer(10);
} }

View File

@ -1,6 +1,6 @@
abstract contract C { contract C {
/// @param id /// @param id
function vote(uint id) public; function vote(uint id) public {}
} }
// ---- // ----
// DocstringParsingError: No description given for param id // DocstringParsingError: No description given for param id

View File

@ -1,6 +1,6 @@
abstract contract C { abstract contract C {
/// @param /// @param
function vote(uint id) public; function vote(uint id) public {}
} }
// ---- // ----
// DocstringParsingError: End of tag @param not found // DocstringParsingError: End of tag @param not found

View File

@ -1,4 +1,4 @@
abstract contract test { abstract contract test {
function functionName(bytes32 input) public returns (bytes32 out); function functionName(bytes32 input) public virtual returns (bytes32 out);
} }
// ---- // ----

View File

@ -2,7 +2,7 @@ abstract contract Test
{ {
function uint256_to_uint256(uint256 x) internal pure returns (uint256) { return x; } function uint256_to_uint256(uint256 x) internal pure returns (uint256) { return x; }
function uint256_to_string(uint256 x) internal pure returns (string memory) { return x == 0 ? "a" : "b"; } function uint256_to_string(uint256 x) internal pure returns (string memory) { return x == 0 ? "a" : "b"; }
function uint256_to_string_storage(uint256) internal pure returns (string storage); function uint256_to_string_storage(uint256) internal pure returns (string storage) {}
function string_to_uint256(string memory x) internal pure returns (uint256) { return bytes(x).length; } function string_to_uint256(string memory x) internal pure returns (uint256) { return bytes(x).length; }
function string_to_string(string memory x) internal pure returns (string memory) { return x; } function string_to_string(string memory x) internal pure returns (string memory) { return x; }
@ -33,10 +33,10 @@ abstract contract Test
} }
} }
// ---- // ----
// TypeError: (1227-1320): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (uint256) pure returns (uint256). // TypeError: (1229-1322): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (uint256) pure returns (uint256).
// TypeError: (1328-1434): Type function (uint256) pure returns (string storage pointer) is not implicitly convertible to expected type function (uint256) pure returns (string memory). // TypeError: (1330-1436): Type function (uint256) pure returns (string storage pointer) is not implicitly convertible to expected type function (uint256) pure returns (string memory).
// TypeError: (1442-1540): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (string memory) pure returns (uint256). // TypeError: (1444-1542): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (string memory) pure returns (uint256).
// TypeError: (1548-1655): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (string memory) pure returns (string memory). // TypeError: (1550-1657): Type function (uint256) pure returns (string memory) is not implicitly convertible to expected type function (string memory) pure returns (string memory).
// TypeError: (1664-1775): Type function (uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256,uint256) pure returns (uint256). // TypeError: (1666-1777): Type function (uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256,uint256) pure returns (uint256).
// TypeError: (1783-1902): Type function (string memory) pure returns (string memory) is not implicitly convertible to expected type function (string memory,uint256) pure returns (string memory). // TypeError: (1785-1904): Type function (string memory) pure returns (string memory) is not implicitly convertible to expected type function (string memory,uint256) pure returns (string memory).
// TypeError: (1910-2034): Type function (string memory) pure returns (string memory) is not implicitly convertible to expected type function (string memory,string memory) pure returns (string memory). // TypeError: (1912-2036): Type function (string memory) pure returns (string memory) is not implicitly convertible to expected type function (string memory,string memory) pure returns (string memory).

View File

@ -4,9 +4,9 @@ interface I {
function f(); function f();
} }
abstract contract C { abstract contract C {
function g(); function g() {}
} }
// ---- // ----
// SyntaxError: (158-171): No visibility specified. Did you intend to add "external"? // SyntaxError: (158-171): No visibility specified. Did you intend to add "external"?
// SyntaxError: (200-213): No visibility specified. Did you intend to add "public"? // SyntaxError: (200-215): No visibility specified. Did you intend to add "public"?
// TypeError: (158-171): Functions in interfaces must be declared external. // TypeError: (158-171): Functions in interfaces must be declared external.