-
Notifications
You must be signed in to change notification settings - Fork 1.7k
voidness propagation as a lint #57770
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
Comments
Right, we have the base level checks enforcing a static approximation1 of "void typed values must be discarded", and voidness preservation is concerned with the higher order version of the same thing, that is, it is concerned with the situation where a "void typed value" is accidentally made available for general usage indirectly: List<void> xs = [1];
List<Object> ys = xs; // OK now, flagged under voidness preservation.
int i = ys[0]; // Oops, nobody should use this value, but we forgot its voidness! We have studied several different approaches to voidness preservation. The obvious starting point is that type transitions (that is, upcasts/downcasts and similar relationships) should not just be guarded by assignability (according to which there is no difference between We don't have implicit "voidness downcasts" (which will stop We did have one other discussion in the language team which is relevant, though: I argued that we should actually erase certain occurrences of top types to abstract class C {
int f1(void x, dynamic y, void Function(void) z);
int f2(Object x, Object y, Object Function(void) z);
} But if the third argument of The point that I'm making is that it is fine that we can enforce that a given implementation of a method does not use one of its arguments (so abstract class I { foo(void x); }
abstract class J { foo(Object x); }
abstract class C implements I,J {} Without this particular kind of "top type erasure" we would have a conflict: "On a receiver With the top type erasure we just have two method signatures for Each method implementation would still be checked without the erasure, of course, so with Footnote 1: Even base level |
Regarding the following case: List<void> x;
List<Object> y = x; what should be do for List<void> x;
List<dynamic> y = x; // OK or not for voidness_propagation ? |
We have two (strong) opinions on |
An other question about inheritance/implementation: is the following code legal regarding voidness? abstract class A {
List m1();
List<void> m2();
List<void> m3();
}
class B extends A {
@override
List<void> m1() => null; // ok or not to replace dynamic by void?
@override
List m2() => null; // ok or not to replace void by dynamic?
@override
List<int> m3() => null; // ok or not to replace void by int?
} |
It would not be OK to override In general, you may think of the subtype lattice as being refined such that But there are several details that we need to settle. For instance, I'd prefer to erase top types to |
Re the two strong opinions: Its probably better to disallow assigning a If it gets implemented as a feature in Dart 3, and for some reason that's done via method 2 while the linter is on 1, then we can rename the lint rule to strict_voidness_propagation. FWIW, void_checks should probably catch:
even though Dart allows it. |
Dart 2 was originally going to have "voidness propagation"
Note that while this is illegal:
A:
this is not an error until runtime:
B:
and worse, this is not an error at all:
C:
A is currently caught by the analyzer, but B & C were supposed to be handled by the not-landed "voidness_propagation."
Currently B is both a runtime error and can be caught by turning off implicit downcasts, but C is completely silent.
We could add this to the linter in the meantime. It also could be added to void_checks, but maybe it would be better to make it "voidness_propagation" because then users who don't want "void_checks" but do want to be future-proof for voidness_propagation could get what they want and nothing more. (this would be a good way to incrementally roll that out as part of the language).
@eernstg
The text was updated successfully, but these errors were encountered: