Unsound `await` handling
See original GitHub issueasync function foo<T>(val: T) {
const v = await val;
return v;
}
async function test() {
const promise = Promise.resolve(1);
const val = await foo(promise);
const a = val.then(); // Runtime error
}
test();
I assume that await
and similar promise methods have signature like this:
await<T>(Promise<T> | T) => T;
This is incorrect. If type of T
is not known to be a promise (i.e. unknown
or generic T
), it is assumed NOT to be a promise, while at runtime it could be a promise.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:5 (2 by maintainers)
Top Results From Across the Web
Asynchronous programming: futures, async, await | Dart
Asynchronous operations let your program complete work while waiting for another operation to finish. Here are some common asynchronous operations: Fetching ...
Read more >Error handling with Async/Await in JS | by Ian Segers | ITNEXT
Now we have the classic problem, thisThrows returns a rejecting promise, so the regular try...catch is not able to catch the error. As...
Read more >Null safe async returns are currently unsound #944 - GitHub
The following program results in a variable of type int containing null (as implemented on the VM, and I believe as currently specified): ......
Read more >Scoped threads in Rust, and why its async counterpart ... - Wisha
Unfortunately, scoped_tasks as envisioned provides an unsound API. How so? Let's demonstrate by abusing the function step-by-step. First, we ...
Read more >Blog post: scoped threads in Rust, and why its async ... - Reddit
Resource leaks in rust (whether memory, a future, a file handle, whatever) are categorically not unsound and not unsafe. When writing safe code, ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Not really fixed though. A tiny modification and you get the same thing:
Let’s say there is a generic type for that called
$Await<T>
which is supposed to evaluate to the type of expressionawait x
wherex
has typeT
.T
can be one of the followingThenable<T>
For thenables,
$Await<Thenable<T>>
equals$Await<T>
.False-thenable
False-thenable is an object, for which
obj.then
evaluates to a function, but it’s not actually a thenable. Applying$Await
to a false-thenable makes no sense, since there is no way to evaluate it.Non-thenable
For everything else
$Await<T>
equalsT
;So here is a possible way to deal with that.
await x
(or Promise.resolve(x) or other) evaluates to type$Await<T>
. Type$Await<T>
can be further refined if we have additional information aboutT
. IfT
is known to be a thenable, we evaluate$Await<Thenable<T>>
to$Await<T>
recursively. IfT
is known to be a non-thenable,$Await<T>
evaluate toT
. Otherwise$Await<T>
should stay opaque, since there is no way to tell what it is.Additionally, it should be illegal to
await
on values, that could possibly be false-thenables. Here is an example: