Skip to content

Commit f33f1d3

Browse files
committed
[Async CC] Always add full type metadata to bindings.
NecessaryBindings are used by both async functions and partial apply forwarders. The latter are able to avoid bindings in some cases because a new function is generated where the information that would otherwise be available in the bindings can be made available. That is not the case for async functions. A generic async function requires all of the metadata and witness tables be passed along to it: unlike a partial apply forwarder it isn't in any way specialized so this information can't be recovered. Previously, metadata bindings were always passed along to async functions. However, destructuring that can be done for partial apply forwarders was still being applied. This resulted in an inappropriate and unexpected number of bindings in NecessaryBindings. Here, that destructuring is avoided for metadata passed to async functions. Now, the full metadata required by async functions are passed along to them as necessary. rdar://problem/71816041
1 parent 87c9cd8 commit f33f1d3

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

lib/IRGen/GenProto.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -2748,8 +2748,16 @@ void NecessaryBindings::save(IRGenFunction &IGF, Address buffer) const {
27482748
void NecessaryBindings::addTypeMetadata(CanType type) {
27492749
assert(!isa<InOutType>(type));
27502750

2751+
// If the bindings are for an async function, we will always need the type
2752+
// metadata. The opportunities to reconstruct it available in the context of
2753+
// partial apply forwarders are not available here.
2754+
if (forAsyncFunction()) {
2755+
addRequirement({type, nullptr});
2756+
return;
2757+
}
2758+
27512759
// Bindings are only necessary at all if the type is dependent.
2752-
if (!type->hasArchetype() && !forAsyncFunction())
2760+
if (!type->hasArchetype())
27532761
return;
27542762

27552763
// Break down structural types so that we don't eagerly pass metadata
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %target-swift-frontend -emit-ir -primary-file %s -enable-experimental-concurrency
2+
3+
func getIntAndString() async -> (Int, String) { (5, "1") }
4+
5+
func testDecompose() async -> Int {
6+
async let (i, s) = await getIntAndString()
7+
return await i
8+
}

0 commit comments

Comments
 (0)