@@ -96,6 +96,25 @@ PolymorphicEffectRequirementsRequest::evaluate(Evaluator &evaluator,
9696 ctx.AllocateCopy (conformances));
9797}
9898
99+ // / Determine whether the given protocol inherits from either
100+ // / AsyncIteratorProtocol or AsyncSequence.
101+ static bool inheritsFromAsyncSequenceProtocol (ProtocolDecl *proto) {
102+ // If it's exactly one of these, shortcut.
103+ if (proto->isSpecificProtocol (KnownProtocolKind::AsyncIteratorProtocol) ||
104+ proto->isSpecificProtocol (KnownProtocolKind::AsyncSequence))
105+ return false ;
106+
107+ auto &ctx = proto->getASTContext ();
108+ if (auto iter = ctx.getProtocol (KnownProtocolKind::AsyncIteratorProtocol))
109+ if (proto->inheritsFrom (iter))
110+ return true ;
111+ if (auto seq = ctx.getProtocol (KnownProtocolKind::AsyncSequence))
112+ if (proto->inheritsFrom (seq))
113+ return true ;
114+
115+ return false ;
116+ }
117+
99118PolymorphicEffectKind
100119PolymorphicEffectKindRequest::evaluate (Evaluator &evaluator,
101120 EffectKind kind,
@@ -117,6 +136,13 @@ PolymorphicEffectKindRequest::evaluate(Evaluator &evaluator,
117136 auto proto = req.getProtocolDecl ();
118137
119138 if (proto->hasPolymorphicEffect (kind)) {
139+ // @rethrows protocols that inherit from AsyncIteratorProtocol or
140+ // AsyncSequence should be categorized like AsyncIteratorProtocol or
141+ // AsyncSequence.
142+ if (kind == EffectKind::Throws &&
143+ inheritsFromAsyncSequenceProtocol (proto))
144+ return PolymorphicEffectKind::AsyncSequenceRethrows;
145+
120146 return PolymorphicEffectKind::ByConformance;
121147 }
122148
0 commit comments