Skip to content

Conversation

@ekpyron
Copy link
Collaborator

@ekpyron ekpyron commented Jan 14, 2020

Fixes #7314 and closes #7987 .

@ekpyron ekpyron force-pushed the declarationsByContractName branch from 4e6e47c to 4a3a67a Compare January 14, 2020 17:29
@ekpyron ekpyron changed the title Clean up visibility via contract name and unimplemented base functions. [WIP] Clean up visibility via contract name and unimplemented base functions. Jan 14, 2020
@ekpyron ekpyron force-pushed the declarationsByContractName branch from 4a3a67a to 1f0c34d Compare January 14, 2020 18:55
@ekpyron ekpyron changed the title [WIP] Clean up visibility via contract name and unimplemented base functions. Clean up visibility via contract name and unimplemented base functions. Jan 15, 2020
@ekpyron ekpyron force-pushed the declarationsByContractName branch from 6c8106e to cf0a9d3 Compare January 16, 2020 11:40
registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, inactive, m_errorReporter);

_declaration.annotation().scope = m_currentScope;
_declaration.annotation().contract = m_currentContract;
Copy link
Contributor

Choose a reason for hiding this comment

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

To be honest, I think we should add a function to the annotation (or a utility function) to determine the contract from the scope instead of storing it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Maybe... it's not like I added it - I just moved it from the annotations of function definitions to declarations - which wouldn't even have been necessary for this PR, but if we have the annotation, then this is the better place for it...

}
bool isVisibleViaContractName() const override
{
return visibility() >= Visibility::Public;
Copy link
Contributor

Choose a reason for hiding this comment

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

not internal?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We could actually allow internal ones... but they would be empty objects with no use... they couldn't be called and don't have a signature and they can't be assigned to anything...

Copy link
Contributor

Choose a reason for hiding this comment

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

Isn't it possible to call them internally?

Copy link
Contributor

Choose a reason for hiding this comment

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

contract A {
    function f() internal virtual pure returns (uint) {return 2; }
}
contract B is A {
    function f() internal virtual override pure returns (uint) {return 3; }
}
contract C is B {
    function g() public pure returns (uint) {
        return A.f();
    }
}

Copy link
Collaborator Author

@ekpyron ekpyron Jan 16, 2020

Choose a reason for hiding this comment

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

That's isVisibleInDerivedContract not this one... but yeah, I'm not sure how to be clearer in the distinction - I renamed it to isVisibleViaContractTypeAccess, maybe that helps, but arguably that's still also what happens in the inheritance case... it's only meant to return true, in case something can be accessed via the contract type name in any context, not merely when inheriting.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah ok, then I see!

functionDefinition &&
_scope &&
functionDefinition->annotation().contract &&
_scope != functionDefinition->annotation().contract &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe this could warrant a different function kind to be honest...

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Like Public? Maybe... not sure if I should do that now, though... I already spent way too much time on this - and I'm not particularly happy with it myself yet, but I'm not sure how much more time we should spend on refactoring this right now...
The problem is that I'd probably need two more kinds PublicWithInternalCallingContext and PublicWithExternalCallingContext... in general it would probably be good to decouple the function type or at least the function type kind from the calling context a bit... but that would require major code changes...

members.emplace_back(stru->name(), stru->type(), stru);
for (auto const& enu: contract.definedEnums())
members.emplace_back(enu->name(), enu->type(), enu);
if (dynamic_cast<ModifierDefinition const*>(declaration))
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Modifiers are not accessible via contract name...

}
// ----
// TypeError: (100-106): Member "f" not found or not visible after argument-dependent lookup in type(contract base).
// TypeError: (100-108): Cannot call function via contract name.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this an error message we had previously?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's the one I added for #8105 .
And I'd say it fits much better here than the old one.

@chriseth
Copy link
Contributor

Ok, I think I get the idea behind this better now that I read all of it :)

chriseth
chriseth previously approved these changes Jan 16, 2020
@chriseth
Copy link
Contributor

Please squash!

@ekpyron
Copy link
Collaborator Author

ekpyron commented Jan 16, 2020

Squashed. I hope you're confident that this really does the same as before in all cases in which it should :-). I think we're still lacking test cases in this area...

@chriseth chriseth merged commit 43ad5ed into develop Jan 16, 2020
@chriseth chriseth deleted the declarationsByContractName branch January 16, 2020 18:33
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.

Calling non-implemented base contracts when overriding causes internal error

4 participants