Closed modulovalue closed 8 months ago
In the case where we're computing the least upper bound of Err
and Leaf
, the least upper bound algorithm in Dart uses a rule, let's call it Rold, which has been part of the language since Dart 1. In general, Rold is used to find the least upper bound of two class types that aren't generic instantiations of the same class.
The rule Rold is specified here.
This rule is rather simplistic and it yields upper bounds that are considerably less tight than they could be. For example, the least upper bound of Err
and Leaf
turns out to be Object
rather than Base<All>
. The basic idea is that it selects the most special shared superinterface of the operands as a whole, and it never applies the least upper bound algorithm on subexpressions of those types. This means that Dart avoids some termination issues that had come up in the context of Java. Moreover, the rule Rold has also been kept unchanged all the time because it is a seriously breaking change to introduce a different rule.
But it is certainly a known issue that the least upper bound algorithm delivers suboptimal results in this particular case. See https://github.com/dart-lang/language/labels/least-upper-bound for more discussions about improving the least upper bounds algorithm.
Note: this issue is relevant to https://github.com/dart-lang/language/issues/844 and https://github.com/spebbe/dartz/issues/32. Anyone trying to do something similar will eventually come across this.
I'm going to close this issue because I don't think that it's likely that many people would benefit from focusing on this issue alone.
I think that a fresh discussion around #844 (and, more broadly, use cases for phantom types, e.g., https://github.com/dart-lang/language/issues/2865 & https://github.com/dart-lang/language/issues/3273) would be needed to make discussing this particular issue worthwhile.
Hello,
Could it be a bug that the type of
listA
isn'tList<Base<All>>
butList<Object>
?My expectation was that the type of
listA
would be the most specific type possible i.e.List<Base<All>>
in this case and notList<Object>
.