-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Name conflicts between base and derived classes #2355
Comments
For consistency, it would be good to make
|
This was discussed a little yesterday, 10-27. For interface name conflicts, if we say
I lean toward the shadowing approach. I think it would cause fewer breakages due to evolution, since |
FWIW, I think both @zygoloid and I were generally happy to explore the shadowing approach here. Some of my thoughts from that discussion capturing here, correct me if I've mis-remembered or am missing anything though: Generally, C++ types do use shadowing even beyond evolutionarily -- for example types that can provide a more refined set of overloads (maybe due to layering exposing more efficient conversion sequences), or types that have a more efficient form of dispatch than (open) virtual dispatch can still short circuit the dispatch when a derived type is statically known. Some of these use cases we can maybe solve more directly with Carbon, but it does seem nice to retain the core expressive functionality here. While I'd somewhat like to have a nice rule that shadows are "compatible" in some way (IE, calls to the base would always be valid calls to the derived), that seems like it might be difficult or impossible to implement so personally I'd not push hard to enforce this in the initial version. I'd still like to make private members of a base completely invisible to derived as I think that's an especially important aspect for evolution -- no conflicts, shadowing, anything in as many cases as we can... We can't do the reverse, but I think that's a much less important direction -- I expect derived classes to be heavily constrained by their base classes. |
Let's call my last post a decision then! |
I think this is a reasonable decision, but there was some significant debate about which path to take in open discussion on Nov 10. Specifically there was debate about how to handle names that are public in the base and have a distinct private definition in the derived class. I'd very much like to better understand and document the lead's rationale for this path rather than the alternatives considered. @chandlerc |
After discussing, I think that the Nov 1 comment gives viable direction for private-in-base and for same access in both base and derived. But I think @josh11b is surfacing that it doesn't actually clarify how exactly we should handle cases with different access levels in base and derived outside of private-in-base. My inclination is to start off restrictive here. In the direction of "we'd like shadowing names to be generally 'compatible' with the name being shadowed", where there are clear incompatibilities like changing the access from non-private to private, I would suggest rejecting that as an incompatible shadow. I would personally be fine allowing other access level changes via shadowing, but I don't feel very strongly about them either way if restricting it would actually be easier to implement or specify in some way. That said, we should make sure we actually have agreement for all of this. =D |
Just to be complete:
My rationale that a
If the name is
|
A related question I'll ask to be resolved here: the design suggests children should be allowed to shadow class functions so that both the child and parent can have a Create function. Can a child shadow a parent's class function with a method, or vice versa? Separately, the previous comment says redeclaring a parent protected method as public seems useful. If a parent has a protected virtual method, can the child have a public non-virtual method of the same name? (I think this could yield somewhat complex rules) |
Proposal (after some discussion with @chandlerc ) about how to handle virtual functions:
|
@chandlerc I think we were saying that shadowing class functions with non-virtual methods and the other way around were both reasonable to us. This is to expose whether the functions need to use the receiver at the calling convention level, while syntactically uniformly using the |
Rereading this comment, it seems the suggestion is to forbid non-
I think reasonably simple rule (for the non-virtual case) would be:
which gives:
|
Refining these rules:
|
Some rationale for the above rules:
So, one way to think about the rules is: we disallow "arbitrary" name hiding between base and derived, but allow two exceptions that end up being quite broad.
[Given the above, I could imagine tightening up exception 2, for example to only apply in the case where the base and derived members are both member functions. But maybe there are cases where you want something else, such as refining a class function with a function-like object or vice versa.] |
Marking this as decided with the results and rationale in the last two comments here. |
Summary of issue:
Do we want:
var derived: Derived
,derived.name
could mean the private member insideDerived
, but the base member outside.Details:
We allow a base and derived class to have class functions with the same name, and this will be used for things like constructors (
Make
). These will be accessed through the class name, and so won't generally create ambiguity.Currently the text of https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/classes.md#virtual-override-keywords says that non-virtual method names can't match/conflict. The behavior for variables is unspecified, but presumably should match.
https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/classes.md#private-access says that
private virtual
andprivate abstract
methods may be implemented/overridden in derived classes. Otherwise, no statement is made about whether a derived class may have variables/methods with the same name as a private member of a base class.In the future work part of the classes design, https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/classes.md#overloaded-methods also talks about this issue.
The text was updated successfully, but these errors were encountered: