Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Public State Variable Overriding #7839

Merged
merged 1 commit into from
Dec 5, 2019
Merged

Conversation

Marenz
Copy link
Contributor

@Marenz Marenz commented Nov 28, 2019

This is a first draft. Please review the general logic if this is done the way we want.
Details like documentation & changelog will be added ones the basics are approved.

refs #5424
fixes #3514

@Marenz Marenz requested a review from ekpyron November 28, 2019 15:57
@Marenz Marenz changed the base branch from develop to develop_060 November 28, 2019 15:57
{
FunctionTypePointer functionType = FunctionType(_function).asCallableFunction(false);
string baseTypeName;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wrong title, should be overridingName

@ekpyron
Copy link
Member

ekpyron commented Nov 28, 2019

Could you add test cases for overriding multiple base functions in multiple inheritance and all the other stuff, even though it won't "work"? It'd still be good to see what happens.

}

if constexpr(std::is_same<T, FunctionDefinition>::value)
if (_overriding.stateMutability() != _super.stateMutability())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether we should take the feature recently brought to light by @fulldecent still into 0.6.0: Allowing to soften the mutability requirements when overriding. It might get complicated because mutability is not a linear order and also when taking multiple inheritance into account, but maybe not...

@chriseth
Copy link
Contributor

That looks really good!

@chriseth
Copy link
Contributor

Even if the check itself seems simple, as @ekpyron we need to check all the cases so that nothing slips under the radar. Things like diamond inheritance where on one branch we have a public state variable and on another we have a function overriding.

@Marenz
Copy link
Contributor Author

Marenz commented Dec 2, 2019

So, this is the output for the diamond test case:

  Contract:
    contract A {
        function foo() external virtual pure returns(uint) { return 5; }
    }
    contract B is A {
        function foo() external virtual override pure returns(uint) { return 5; }
    }
    contract C is A {
        function foo() external virtual override pure returns(uint) { return 5; }
    }
    contract X is B, C {
        uint public override foo;
    }

    TypeError: (271-320): Derived contract must override function "foo". Function with the same name and parameter types defined in two or more base classes.

And it's the same for normal multiple inheritance..

@Marenz
Copy link
Contributor Author

Marenz commented Dec 2, 2019

    contract A {
        uint public foo;
    }
    contract B {
        function foo() external virtual pure returns(uint) { return 5; }
    }
    contract X is A, B {
        uint public override foo;
    }

This currently works, but I would suspect this will no longer work once @christianparpart variable shadow PR is merged

@Marenz Marenz force-pushed the state-var-override branch from 317a891 to 80cc625 Compare December 2, 2019 16:34
@Marenz Marenz marked this pull request as ready for review December 2, 2019 16:34
@Marenz Marenz requested a review from chriseth December 2, 2019 16:34
@Marenz
Copy link
Contributor Author

Marenz commented Dec 2, 2019

This is now ready

Changelog.md Outdated Show resolved Hide resolved
docs/contracts/inheritance.rst Outdated Show resolved Hide resolved
docs/contracts/inheritance.rst Outdated Show resolved Hide resolved
@Marenz Marenz force-pushed the state-var-override branch from 9452104 to 44009c3 Compare December 3, 2019 09:13
@@ -244,6 +244,27 @@ overridden when used with multiple inheritance:

Functions with the ``private`` visibility cannot be ``virtual``.

Public state variables can override external functions with no parameters if the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about

interface ERC20 {
  function balanceOf(address) external view returns (uint);
}
contract C {
  mapping(address => uint) public balanceOf;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That compiles.. should it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I didn't add the is IRC20 part in my test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still works with the fixes

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then please change the documentation.

@Marenz
Copy link
Contributor Author

Marenz commented Dec 3, 2019

Apparently I am not checking that the parameters are null.. need to fix that

@chriseth
Copy link
Contributor

chriseth commented Dec 3, 2019

Please add a test that shows how this works with overloading, i.e. two functions with the same name in the base contract, once the case where one of the functions matches with regards to parameter types and one case where none of the two match.

@Marenz Marenz force-pushed the state-var-override branch from 44009c3 to 59acbe5 Compare December 3, 2019 13:48
@Marenz
Copy link
Contributor Author

Marenz commented Dec 3, 2019

Added the cases and extended the logic a bit

@leonardoalt
Copy link
Member

Needs to be rebased.
Is it ready for re-review besides rebasing?
@Marenz

it = find_if(++it, funcSet.end(), MatchByName{stateVar->name()})
)
{
if ((*it)->visibility() != Declaration::Visibility::External)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it on purpose that this check is not done after the next?

@chriseth
Copy link
Contributor

chriseth commented Dec 4, 2019

Rebasing this.

@chriseth chriseth force-pushed the state-var-override branch 3 times, most recently from c1bdc65 to accd83e Compare December 4, 2019 14:06
@chriseth chriseth force-pushed the state-var-override branch 2 times, most recently from 2635e0a to ea76d98 Compare December 4, 2019 14:12
uint public foo;
}
// ----
// TypeError: (100-115): Base function must be external when overridden by public state variable.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still not too happy with this error message, but it might be fine. At least the error is on the state variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could change it to Public state variable cannot override non-external function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or can only override external function

Copy link
Contributor Author

@Marenz Marenz Dec 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(functions with external visibility)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not happy with it because at this point, we do not yet know whether we have the 'override' specifier given or not.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is specified, then the message is correct.
If it's not, then when they fix the external function, the new message override required here will appear, so I guess also fine

@chriseth chriseth changed the title Public State Variable Overridding Public State Variable Overriding Dec 4, 2019
Copy link
Contributor Author

@Marenz Marenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me, can't approve my own PRs though

@Marenz
Copy link
Contributor Author

Marenz commented Dec 4, 2019

Rebased and squashed.

leonardoalt
leonardoalt previously approved these changes Dec 5, 2019
@leonardoalt leonardoalt dismissed their stale review December 5, 2019 12:37

Tests failing

@leonardoalt
Copy link
Member

I think some of the test failures are actually correct

@Marenz Marenz force-pushed the state-var-override branch from d6cf3a0 to b7d5de5 Compare December 5, 2019 12:49
@Marenz
Copy link
Contributor Author

Marenz commented Dec 5, 2019

fixed three tests that expected the wrong phrasing

@chriseth chriseth merged commit 1890d17 into develop_060 Dec 5, 2019
@chriseth chriseth deleted the state-var-override branch December 5, 2019 13:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants