-
Notifications
You must be signed in to change notification settings - Fork 207
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
Specify error for await e
where the type of e
has something to do with an extension type
#3473
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,9 @@ information about the process, including in their change logs. | |
[1]: https://github.com/dart-lang/language/blob/master/working/1426-extension-types/feature-specification-views.md | ||
[2]: https://github.com/dart-lang/language/blob/master/working/extension_structs/overview.md | ||
|
||
2023.11.17 | ||
- Correct the rule about extension types and `await` expressions. | ||
|
||
2023.10.31 | ||
- Simplify the rules about the relationship between extension types and the | ||
types `Object` and `Object?`. | ||
|
@@ -826,9 +829,18 @@ _is the extension type_ | |
<code>V\<T<sub>1</sub>, .. T<sub>s</sub>></code>, | ||
and that its static type _is an extension type_. | ||
|
||
We say that an extension type is _unrelated to `Future`_ in the case where | ||
it does not implement `Future<U>` for any `U` *(this means that it has no | ||
direct or indirect superinterface of the form `Future<...>`)*. | ||
|
||
It is a compile-time error if `await e` occurs, and the static type of | ||
`e` is an extension type which is not a subtype of `Future<T>` for any | ||
`T`. | ||
`e` satisfiers at least one of the following criteria: | ||
|
||
- an extension type which is unrelated to `Future`. | ||
- a type of the form `T?` or `FutureOr<T>` where `T` is a type that matches | ||
one of the items in this list. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we give the property of being in the list a name, then we can refer to it recursively here. Say:
(IIRC, a type is trivially bounded by itself, which I guess is why you use the "one of the earlier items" phrase to avoid infinite regress. I guess calling it a coinductive definition would allow the infinite recursion.) |
||
- a type which is `T` bounded, where `T` matches one of the earlier items | ||
*(this covers type variables and intersection types)*. | ||
|
||
A compile-time error occurs if an extension type declares a member whose | ||
basename is the basename of an instance member declared by `Object` as | ||
|
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 think we should not include
FutureOr<T>
here. The typeFutureOr<T>
is very much releated toFuture
, even ifT
isn't. Actually, especially ifT
isnt.You should be allowed to await
FutureOr<Ext>
whereExt
is an extension type unrelated toFuture
.We want to allow you to await
FutureOr<T>
for anyT
, because otherwise you'd have to do an(v is Future<T>) ? await v : v
, which would be allowed and have all the same issues as what we are trying to avoid by disallowing it.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.
Well, the point was that if you have an expression of type
E
which is an extension type that has no relation toFuture
then you can trivially type that same expression asFutureOr<E>
, which we can think of asFuture<E> | E, and then it seems contradictory if it's ok to await that, but it is not OK to await
E` alone. So I classified all the unions including the "don't await me" type as "don't await me" as well.We could drop this whole idea and say that (1) await just uses the extension type erasure, no matter what (also for computation of the type of
await e
), and (2) it's up to a lint to tell people that it's a violation of some notion of encapsulation to have this particular await expression.