language icon indicating copy to clipboard operation
language copied to clipboard

Feature spec of explicit variance

Open eernstg opened this issue 5 years ago • 4 comments

This is a first draft version of the feature specification of explicit variance support in Dart: (1) Explicit variance modifiers out/inout/in that generic type declarations can use on their type parameters, and (2) an explicit invariance modifier exactly on type arguments that client code can use in order to obtain statically safe use of legacy classes (using the current kind of covariance which requires dynamic checks).

It is rather permissive, in the sense that it allows for things like class B<out X> extends A<X> {} where A is a legacy class (say, class A<X> { foo(X x) {}}), which means that we can have a variable b of type B<num>, and we can call b.foo(1.23), and it will throw at run-time.

We could also say that the method foo is inaccessible in B (just like Java wildcards: we could "filter" out the part of the API whose member signatures violate the given variance). But I suspect that it will work better in practice to catch such cases with a lint.

Member declarations involving type parameters that have explicit variance modifiers are checked strictly (so class B<out X> { void foo(X x) {...}} is a compile-time error), but it is of course always possible to check such properties in the body and throw (void foo(Object? o) { X x = o as X; ...}), and, with that, I saw no reason to prohibit covariant parameters.

eernstg avatar Sep 02 '19 17:09 eernstg