@@ -96,6 +96,25 @@ PolymorphicEffectRequirementsRequest::evaluate(Evaluator &evaluator,
96
96
ctx.AllocateCopy (conformances));
97
97
}
98
98
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
+
99
118
PolymorphicEffectKind
100
119
PolymorphicEffectKindRequest::evaluate (Evaluator &evaluator,
101
120
EffectKind kind,
@@ -117,6 +136,13 @@ PolymorphicEffectKindRequest::evaluate(Evaluator &evaluator,
117
136
auto proto = req.getProtocolDecl ();
118
137
119
138
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
+
120
146
return PolymorphicEffectKind::ByConformance;
121
147
}
122
148
0 commit comments