-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Strong mode: Disallow private collisions induced via mixin #28809
Comments
Is there a test case for this? (There's not a lot of detail in this issue, and nobody has volunteered to own the issue.) |
Writing down the test cases for this seems like a very useful exercise. I'll see if I can find time or someone to take a stab at that. The basic idea is that two private members (fields, getters, setters, and methods) with the same name from the same library shouldn't be allowed to be mixed together through mixin applications in other libraries. |
So would the following be an example?
|
If |
Right, what @kasperl said. In general, when a programmer is applying a mixin from a different library, the analyzer will need to check that it doesn't cause a private member collision (which must also involve a class/mixin in that other library). The intent is to let the programmer and compiler reason about a library's private members without worrying about how downstream code may accidentally use them / override them. The intuition is that it's unlikely that the downstream programmer intended the private member conflict. |
I'm working my way toward a guess at the specification, but I should have started by asking whether there is an informal spec for this. If so, you can probably ignore this next question. So what about indirect in-mixing? For example, if we have in lib1.dart:
and in lib2.dart:
|
This thread is probably the closest thing to an informal spec right now. :-) Yes, the intent is that would be a collision. |
How does the following sound for a first cut toward an informal(-ish) spec:
Does that match your expectations? |
I don't think that covers this case: lib1.dart:
lib2.dart:
|
Ah. Then I take it we want to include all of the superclasses of C in the list of classes being checked. Is it true that we can ignore interfaces (because they won't contribute private members)? |
Right, I believe spec linearizes the mixins so you can consider them one at a time (and the application of any previous ones to be already be in the superclass chain). So, if you're mixing in a class from a different library, check the superclass chain for a conflict on any private member. Does that sound right to you? I think you're correct on interfaces. |
I'm not sure. What about this example:
lib2.dart:
Should there be an error for Is it only an error for conflicts that are directly mixed in by the declaration of C? For example, I suspect that there should be no errors in the following:
lib2.dart:
|
I think those examples are fine (i.e., no error). In neither case does Part of the intent here is to let us look at |
I don't understand what you mean by that. Given that the conflicting private methods are by definition from a different library, you have to look outside |
You should be able to look at Today,
That should also trigger an error. |
Ok. I have a first cut at implementing this error, but I can't commit it because it breaks the build. It breaks the build because dart2js contains a violation of this rule. The error occurs here (https://github.com/dart-lang/sdk/blob/master/pkg/compiler/lib/src/tree/nodes.dart#L2504) and is cause by the fact that Do we need to rethink / redefine this error, or do we need to fix dart2js? |
/cc @sigmundch @rakudrama |
Thanks, Brian. Is that the only error you're seeing the SDK? Looks like these are the types in question: |
Actually, all I saw was a build bot failure saying that the kernel snapshot couldn't be built, so I asked for help. Vyacheslav investigated and pointed out this failure. I didn't ask whether this was the only failure; I assumed he would have said so if there were more. Yes, that's one of the types. The other is on line 33 of the same file. |
/cc @johnniwinther
FWIW - here is a simplified snippet of the code you linked above: class I {
get _x;
set _x(v);
}
class N implements I {
get _x => null;
set _x(v) => throw "";
}
class S implements I {
Object _x;
}
// lib2.dart:
class B extends N {}
class C extends B with S {}
|
The objective is for this to only be a strong-mode error. Brian was checking everything. If this code is never intended to be strong mode clean, I don't think you need to do anything. There is no immediate (1.23) plan for |
We could apply one of these two CLs to make dart2js conform to the restrictions. https://codereview.chromium.org/2722923002 I think this feature (the aggregation of an implementation that has a private contract) is useful and would like it to be supported in a future version of dart. |
I have updated my CL to only generate the error in strong mode. In so doing I had to update the 4 tests I had written to be run in strong mode. That turned up the interesting information that 3 of the 4 tests also produce an error with the StrongModeErrorCode.INVALID_FIELD_OVERRIDE error code. Maybe it's just the tests I came up with, but it seems like we shouldn't need two errors that are this likely to be produced together. |
This change is to enable the elimination of the INVALID_FIELD_OVERRIDE error. All fields will become virtual in strong mode, modulo the restriction from this issue. |
Brian, thanks so much for working on this. How far are you with landing this? |
The CL has been approved and is ready to land, but is held up by other work. |
Undo the accidental close. |
I have committed one of the CLs that makes dart2js 'clean' with respect to this warning. |
Thanks! Do we have an estimate for when the other CLs might be ready? |
I think @rakudrama looked at multiple potential fixes for the same warning and decided which one to land (and landed it). I don't think we're waiting on the rest. |
@bwilkerson what's remaining here? |
This is now an error in strong mode. See: dart-lang/sdk#28809 BUG= R=kevmoo@google.com Review-Url: https://codereview.chromium.org//2778923002 .
…_APPLICATION. Originally specified in #28809 There was a couple of holes in our unit tests, so we missed a rare situation when the issue should not be reported. R=brianwilkerson@google.com, paulberry@google.com Change-Id: Iaf35a7755c4ac4fc69bd86c56f18dc0a952bf7fd Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/128523 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
We want to introduce an error in strong mode that flags all private member (field/getter/setter/method) collisions induced by a separate library applying a mixin.
The suggested name for the error is StrongMode.PRIVATE_COLLISION_IN_MIXIN_APPLICATION.
The text was updated successfully, but these errors were encountered: