-
Notifications
You must be signed in to change notification settings - Fork 208
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
Subtyping rules for nullable types and legacy migration types #151
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's the review that I promised. Lasse just landed the PR, but any upcoming changes could be handled in a new PR.
- `Function` | ||
- `Future<T>` | ||
- `FutureOr<T>` | ||
- `T?` | ||
- `T*` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to address T!
as well, such that we know whether there will be any difficulties with it if we choose to introduce it.
Btw, we will need to consider whether T*
gets into the language specification; alternatively, we could keep them in a feature specification like this one, because they are not supposed to exist forever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a revision that explores how to deal with T!
, I'll try to get back to it tomorrow.
semantically as the union type `T | Null`. | ||
|
||
The type `T*` represents a legacy type which may be interpreted as nullable or | ||
non-nullable as appropriate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point I'd add (some commentary) indicating that (1) legacy types are not expected to have a sound static analysis, and (2) legacy types will be eliminated from the language after a while.
|
||
- **Left Legacy Null** `T0` is `Null*` | ||
|
||
- **Left and Right Legacy** `T0` is `S0*` and `T1` is `S1*` and `S0 <: S1`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would not allow us to conclude List<Null*> <: List<int*>
, because that will require Null <: int
. Wouldn't that break too much existing code?
(Left Legacy and Right Legacy can't do it, either.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, agreed, I realized that my treatment of T*
in this CL is completely broken, I have revised it from first principles in a follow on. Will send out shortly.
@@ -121,12 +134,31 @@ We say that a type `T0` is a subtype of a type `T1` (written `T0 <: T1`) when: | |||
|
|||
- **Right Top**: `T1` is a top type (i.e. `Object`, `dynamic`, or `void`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's being discussed here whether Object
should be a top type, or it should be spelled Object?
. If the latter is chosen, 'Right Top' should only mention dynamic
and void
.
This updates the informal description of the subtyping rules (including the derivation of the algorithmic syntax directed rules) for non-null by default types. It also adds rules for handling the legacy types planned for use during the migration when non-opted-in libraries interact with opted-in libraries.
cc @stereotype441 @bwilkerson @kmillikin @lrhn