Concurrency: fix inconsistent _asyncLet_get signatures #4288
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Resolve #4250
How did I find the root issue (memo)
Given this snippet,
Run
$ swiftc -emit-ir -Xfrontend -disable-swift-specific-llvm-optzns -parse-as-library test.swift -o test.ll
to check LLVM IR before CoroSplit pass. Then, it outputs the below instruction.@llvm.coro.suspend.async
is an LLVM intrinsic which indicates a suspension point. The CoroSplit pass splits a function into several resumption functions at the suspension points. The generated function takes the value returned by the function passed to the suspension asynchronously. ({ i8*, i8* }
) Note that the asynchronously returned type is not the type returned synchronously.swift_asyncLet_get
returns nothing synchronously, but it passes twoi8*
to the resumption function, sollvm.coro.suspend.async
's result type is declared as{ i8*, i8* }
.In the above example, the function and the resumption function generated from the suspension point would be transformed by CoroSplit pass:
As I said before, the resumption function (
s4test10EntrypointVAAyyYaFZTY1_
) takes two parameters.However,
swift_asyncLet_get
passes only an async context, so it crashes on wasm due to signature mismatch.So, who determines the async result type of
swift_asyncLet_get
? The result type is computed bySignatureExpansion::expandAsyncAwaitType
and its input is the intrinsic function declaration at stdlib. The Swift level declaration says that it returns async context and a pointer asynchronously, but its implementation returns only async context. That's the mismatch.