-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bounds of a generic type alias ensure the body is regular-bounded
The analyzer enforces the rule that when a generic type alias F has formal type parameters X1..Xm with bounds B1..Bm, if we assume that X1..Xm are types satisfying the corresponding bounds then it must be the case that every type which occurs in the body of F must be regular-bounded. In other words, the bounds on the left hand side of `=` must imply the bounds applicable to every type on the right hand side. ---------- NEW TEXT ---------- I just discovered that it is _not_ possible to skip the check on every super-bounded parameterized type based on a generic type alias: It is certainly possible to have a type which is correctly super-bounded according to the type parameter bounds on the left hand side of `=` in the type alias declaration, and still have a right hand side where some types are not well-bounded. Consider the following declarations: class B<Y1 extends Y2, Y2, Y3 extends num> {} typedef F<X extends num> = B<num, Object, X> Function(); According to the declarations to the left of `=`, `F<Object>` is a correct super-bounded type, because it is not regular-bounded (`Object <\: num`), and `F<Null>` is regular-bounded (`Null <: num`). Also, when the declared bound of `X` is satisfied, we are guaranteed that each type on the right hand side is regular-bounded (if parameterized, it receives type arguments that satisfy all the specified bounds). But consider the result of applying `F` to `Object`: B<num, Object, Object> Function(); That's not a type where all subterms which are types are well-bounded: B<num, Object, Object> is not regular-bounded because `Object <\: num` (third type argument). B<num, Object, Object> is not super-bounded because B<num, Null, Null> is not regular-bounded because `num <\: Null` (violating `Y1 extends Y2`). So there is no way we can prove that this check can be skipped, because we have a pretty simple counter-example! I'm currently adjusting the text to re-introduce the check. ---------- OLD TEXT, NOT VALID ---------- This must be specified, because it justifies the _removal_ of a requirement that we had in the feature specification super-bounded-types.md: It was required for every application of a generic type alias F to a list of actual type arguments <T1..Tk> such that the resulting parameterized type F<T1..Tk> was super-bounded that both the parameterized type F<T1..Tk> and every type in the resulting type [T1/X1..Tk/Xk]U (where U is the body of F and X1..Xk are its formal type parameters) be well-bounded. But when the bounds of F imply satisfaction of the bounds of all types that occur in the body of F, it's trivially true that all types in the resulting type are regular-bounded for the result of substituting Null for covariant top types and Object for contravariant Null for every super-bounded F<T1..Tk>. I'm looking into a proof sketch for the result that this implies that any well-bounded generic type alias application yields a type that contains only well-bounded types. This would be a very welcome simplification (because it was an inconvenient complication that we had to check both the left hand side and the right hand side of a type alias whenever we encountered a super-bounded type expressed via a type alias), and I believe that it will also make the tools run faster (because they can now skip all those checks of every type that occurs in the body for every super-bounded usage of a type alias. Change-Id: Icd70649ebaed41b193aeb0cb6f08d06aed0ee5bd Reviewed-on: https://dart-review.googlesource.com/c/79743 Reviewed-by: Leaf Petersen <leafp@google.com> Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
- Loading branch information
Showing
2 changed files
with
103 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters