-
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 beyond inheritance #2745
Comments
My initial thoughts -- I'd be happy to generalize the rule we have for inheritance in #2355 for other cases of a class extending something and explicitly declaring a name -- the explicit name shouldn't be obviously incompatible but otherwise shadows. I don't have strong feelings on whether we want anything beyond "doesn't change the access level" for "obviously incompatible". While any restrictions here do present some evolution hazards, I feel like the balance we struck in #2355 is similarly reasonable elsewhere (to the extent it applies). I'm much less clear on what we should do for extending two things and resolving a conflict between them. Part of my hesitation with rejecting in the face of conflicts is that it doesn't seem like it leaves the user many good options at all. Would be interested to hear other ideas for how we should or shouldn't handle these. |
To be concrete, here is an example:
To me, it seems like
This is consistent with our approach to the Another choice, specifically the one we chose before when implementing two interfaces internally with a name in common, was to report an error The cases of Case It does seem like we'd like the policy to be consistent across extending an interface, a base class, and an adapter. This will make it easier to teach and remember, and make it more likely that the policy also applies when we want to answer this question for mixins in the future as well. |
My suggested resolution is:
Note that there is some extra complexity to this last point, since we may have two different things in extensions that are being "refined" by the new definition in the class, as in:
|
Another question is how |
can we modify this example like this.... to resolve this name conflict error..
ig there are many ways but we can do this also i hope this make it will help 😊.... |
@officialhemant511 FYI I've edited your comment to fix the formatting. It looks like the only differences in your version are:
Are you suggesting that the name resolution behavior should change depending on whether the function body of |
@officialhemant511 I'm not sure if my post was clear: the goal is to show various examples where name conflicts can occur and decide what happens in each of those situations. |
Since interfaces are public, if the shadowed name comes from an interface like This means that if an interface adds a new method that is shadowed by classes extending it, the compile does not break and existing code remains the same - calling the method in the class not the extension interface.
This feels consistent with a facet type that has multiple names that collide, which I think you also cited above. It does mean that if a class extends two interfaces, adding a method to one interface can break compile for users of that extending class. But it won't change runtime behaviour on them silently. The other option here is I think to break compile of the I think I would argue for doing the latter and breaking consistency with building a facet with Whereas with
Were you specifically thinking of non-public visibility here, or other criteria? Or maybe leaving it open in case further criteria come in the future for base classes?
Allowing this shadowing seems to match the semantics of #2355, which is both a simple rule to explain and consistent then for interfaces and inheritance. After all, it is hard to know what "refinement" means from the compiler.
Giving a concrete example.
Like in the I did not understand what "allow extending an incomplete interface" means, is it this?
Or could you clarify what that point means? |
(Edit: I was wrong, here is a better answer.) I think it is talking about interfaces extending an interface for which we only have a forward declaration. In general, since we have decided to go with the "declare before use" approach, there is pressure to allow as many things as possible to support using an incomplete declaration instead of requiring that they be defined before use. This helps developers to break cycles and put their code in an order that they prefer. But we won't do it if it causes too much compiler complexity, for example having to re-evaluate a bunch of code once we finally see the definition. Also note that current Carbon doesn't have the flexibility to So the case is:
|
Summary of issue:
#2355 defines the behavior of name conflicts arising from inheritance. There are two other kinds of name conflicts that can arise in classes from using
extend
(of #995) to extend the API of a class:extend
things other than a base class, and some member in the class can conflict with a member with the same name in the thing being extended: extending adapter, mixin, and internal impl.extend
more than one thing, and more than one of the things being extended can have a member of the same name.We can have both of these issues, where there are members with the same name in the class and multiple things being
extend
ed. This is in fact a likely way people will want to resolve the ambiguity of having a name conflict in the things beingextend
ed.What are the rules for resolving these name conflicts, and how do they interact with the restrictions from #2355?
The text was updated successfully, but these errors were encountered: