Open stereotype441 opened 3 years ago
The usual argument against using "LUB" is that the type system might cause unexpected values to surface.
The classical example was LUB computations which ended up with the private _EfficentLengthIterable<T>
class instead of the least upper public bound of Iterable<T>
that the user expected. If you make a list of that, you can't add other Iterable<T>
s.
Also, promoting x
to num
here, even though num
is not a "type of intertest", makes it non-obvious why
if (x is int) {
...
} else {
x = 2.0;
}
will not promote to num
as well (It doesn't because the x = 2.0;
doesn't promote, because double
is not a type-of-interest). It can make it harder to explain the limits of promotion.
I would totally accept promoting if one of the joined types is a supertype of the other, because then the result is a type-of-interest. The usability risks of exposing LUB types worries me quite a lot.
(I'd be interested in considering a "partial promotion" variant where a partially promoted variable allows member invocations at the promoted type, and assignment to the promoted type, but otherwise its own static type is not affected, so, say, creating a list containing it won't cause the list to use the partially promoted type as element type.)
(This suggestion has come up a few times, most recently in https://github.com/dart-lang/sdk/issues/47105.)
Flow analysis currently maintains a list of promoted types for each variable called the variables promotion chain. When two control flow paths are joined, the promotion chains for each variable are intersected (meaning we retain any promotions made on both control paths, but exclude any promotions made on only one path or another). When types get excluded by this algorithm, we don't make any effort to replace them with a least upper bound.
So for example, this doesn't work:
In principle, flow analysis could be smarter and see that after the
if
statement, sincex
has either typeint
ordouble
, it must have typenum
, in which casex + 1
would be allowed.I think a lot of the reason this sort of thing surprises people is that there are other places where the language does use least upper bound, for example: