Merge pull request #5486 from ethereum/allowExternalPublicOverride

Allow external public override
This commit is contained in:
chriseth 2018-11-26 14:26:55 +01:00 committed by GitHub
commit 7921e5f0b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 39 additions and 10 deletions

View File

@ -1,6 +1,7 @@
### 0.5.1 (unreleased)
Language Features:
* Allow public functions to override external functions.
Compiler Features:

View File

@ -413,16 +413,14 @@ void TypeChecker::checkFunctionOverride(FunctionDefinition const& _function, Fun
if (_function.visibility() != _super.visibility())
{
// visibility is enforced to be external in interfaces, but a contract can override that with public
if (
_super.inContractKind() == ContractDefinition::ContractKind::Interface &&
_function.inContractKind() != ContractDefinition::ContractKind::Interface &&
// Visibility change from external to public is fine.
// Any other change is disallowed.
if (!(
_super.visibility() == FunctionDefinition::Visibility::External &&
_function.visibility() == FunctionDefinition::Visibility::Public
)
return;
overrideError(_function, _super, "Overriding function visibility differs.");
))
overrideError(_function, _super, "Overriding function visibility differs.");
}
else if (_function.stateMutability() != _super.stateMutability())
overrideError(
_function,
@ -433,7 +431,6 @@ void TypeChecker::checkFunctionOverride(FunctionDefinition const& _function, Fun
stateMutabilityToString(_function.stateMutability()) +
"\"."
);
else if (functionType != superType)
overrideError(_function, _super, "Overriding function return types differ.");
}

View File

@ -14062,6 +14062,21 @@ BOOST_AUTO_TEST_CASE(flipping_sign_tests)
ABI_CHECK(callContractFunction("f()"), encodeArgs(true));
}
BOOST_AUTO_TEST_CASE(external_public_override)
{
char const* sourceCode = R"(
contract A {
function f() external returns (uint) { return 1; }
}
contract B is A {
function f() public returns (uint) { return 2; }
function g() public returns (uint) { return f(); }
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f()"), encodeArgs(2));
ABI_CHECK(callContractFunction("g()"), encodeArgs(2));
}
BOOST_AUTO_TEST_SUITE_END()
}

View File

@ -0,0 +1,7 @@
contract A {
function f() external pure {}
}
contract B is A {
function f() public pure {
}
}

View File

@ -0,0 +1,10 @@
contract A {
function f() external pure {}
}
contract B is A {
function f() public pure {
super.f();
}
}
// ----
// TypeError: (106-113): Member "f" not found or not visible after argument-dependent lookup in contract super B.

View File

@ -4,4 +4,3 @@ contract C {
}
// ----
// DeclarationError: (17-66): Function with same name and arguments defined twice.
// TypeError: (17-66): Overriding function visibility differs.