Skip to content

Commit 6a37877

Browse files
committed
Teach the old associated type inference about AsyncSequence.Failure
The new one is smart enough to figure out a type witness for AsyncSequence.Failure from AsyncSequence.AsyncIterator.Failure, but the old one doesn't have general logic to handle cases like these. Introduce a bespoke rule to keep the old/new associated type inference logic in sync for the newly-introduced Failure type.
1 parent b7147a2 commit 6a37877

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

lib/Sema/AssociatedTypeInference.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,10 +2299,29 @@ AssociatedTypeInference::computeAbstractTypeWitness(
22992299
if (const auto &typeWitness = computeDefaultTypeWitness(assocType))
23002300
return typeWitness;
23012301

2302-
// Ignore the default for AsyncIteratorProtocol.Failure and
2303-
// AsyncSequence.Failure. We use the next() function to do inference.
2304-
if (isAsyncIteratorProtocolFailure(assocType))
2302+
// Don't consider the generic parameter names for AsyncSequence.Failure or
2303+
// AsyncIteratorProtocol.Failure; we always rely on inference from next() or
2304+
// next(_:).
2305+
if (isAsyncIteratorProtocolFailure(assocType)) {
2306+
// If this is specifically AsyncSequence.Failure with the older associated
2307+
// type inference implementation, our abstract witness is
2308+
// "AsyncIterator.Failure". The new implementation is smart enough to do
2309+
// this from the same-type constraint.
2310+
if (!ctx.LangOpts.EnableExperimentalAssociatedTypeInference &&
2311+
proto == assocType->getProtocol() &&
2312+
proto->isSpecificProtocol(KnownProtocolKind::AsyncSequence)) {
2313+
auto iterAssoc = proto->getAssociatedType(ctx.Id_AsyncIterator);
2314+
auto iteratorProto =
2315+
ctx.getProtocol(KnownProtocolKind::AsyncIteratorProtocol);
2316+
auto iteratorFailure = iteratorProto->getAssociatedType(ctx.Id_Failure);
2317+
Type iterType = DependentMemberType::get(
2318+
proto->getSelfInterfaceType(), iterAssoc);
2319+
Type depType = DependentMemberType::get(iterType, iteratorFailure);
2320+
return AbstractTypeWitness(assocType, depType);
2321+
}
2322+
23052323
return llvm::None;
2324+
}
23062325

23072326
// If there is a generic parameter of the named type, use that.
23082327
if (auto genericSig = dc->getGenericSignatureOfContext()) {

test/Concurrency/async_iterator_inference.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
// RUN: %target-swift-frontend -strict-concurrency=complete -emit-sil -o /dev/null %s -verify -disable-availability-checking
1+
// RUN: %target-swift-frontend -strict-concurrency=complete -emit-sil -o /dev/null %s -verify -disable-availability-checking -enable-experimental-associated-type-inference
2+
// RUN: %target-swift-frontend -strict-concurrency=complete -emit-sil -o /dev/null %s -verify -disable-availability-checking -disable-experimental-associated-type-inference
23
// REQUIRES: concurrency
34

45
@available(SwiftStdlib 5.1, *)

0 commit comments

Comments
 (0)