-
Notifications
You must be signed in to change notification settings - Fork 27
Support B <: A<bottom> #324
Comments
Another interesting variant - change This comes up in practice here for I think you could work around this by making DefaultEquality generic, but that may introduce extra objects in memory. |
The factory constructor should be rejected - presumably we've just not inserted our stronger check in factory constructors? I think making B implement |
Is this fixed with the move to task model? I seem to be seeing these errors now. |
yep, should be fixed now ... though we were still wondering about perhaps supporting this case somehow? e.g. maybe marking it as a contravariant interface |
Two thoughts about this:
For either of these though, we need some way of tracking and checking variance in the element and type model. |
Yeah. +1 on the first option. The C# theory of variance was that most programmers probably wouldn't use it much or understand it very well. So explicit marking was okay. It was mainly intended for a small set of core library types that are very heavily used, but not many people have to implement them (Func types, compare/equality interfaces, Enumerable, and other things of that nature). So folks ultimately benefit from the co/contravariance annotations without ever having written one. It "just works". Just my opinion, but I think this theory was borne out in practice. That said, literacy on types seems to be increasing generally, so in some sense, I'd be even less worried about an explicit annotation nowadays. If we're going to keep default covariance, I can haz invariant annotation plz? ;-) |
B <: A<bottom>
Repurposing the bug. We do now type check the redirecting constructor. This particular example is sound, but we're not flexible enough to support it. |
What's the safest backwards compatible option? Full contra-variance (which is really what OTOH, we could allow some way of expressing |
If I understand correctly, we could allow the contravariance for type parameters, but only where they are is For example: abstract class Equality</*in*/ E> {
const factory Equality() = DefaultEquality;
bool equals(E e1, E e2);
// ...
}
class DefaultEquality implements Equality {
bool equals(e1, e2) => e1 == e2;
// ...
}
class MyEquality implements Equality<Object> { ... }
main() {
// This is allowed, because Equality<dynamic> <: Equality<T> for all T.
Equality<int> e = new DefaultEquality();
// this wouldn't be allowed, MyEquality is an Equality<Object>.
// we'd like it to, but normal Dart checked mode will reject:
Equality<int> e2 = new MyEquality();
// this wouldn't be allowed either. In other words, no covariance.
Equality<num> e3 = e;
// Like the second example, this doesn't work even thought we'd like it to:
Equality<int> e4 = e3;
} (using "in" to match C# naming convention.) |
moved to dart-lang/sdk#25604 |
The following code show no strong errors and warnings but runs and prints "hello". I.e.,
foo
is incorrectly called with a String.@leafpetersen should we reject the factory constructor below?
The text was updated successfully, but these errors were encountered: