File tree Expand file tree Collapse file tree 2 files changed +46
-0
lines changed Expand file tree Collapse file tree 2 files changed +46
-0
lines changed Original file line number Diff line number Diff line change @@ -170,6 +170,11 @@ class ProtocolConformanceRef {
170
170
// / Map contextual types to interface types in the conformance.
171
171
ProtocolConformanceRef mapConformanceOutOfContext () const ;
172
172
173
+ // / Look up the type witness for an associated type declaration in this
174
+ // / conformance.
175
+ Type getTypeWitness (Type origType, AssociatedTypeDecl *assocType,
176
+ SubstOptions options = std::nullopt) const ;
177
+
173
178
// / Given a dependent type (expressed in terms of this conformance's
174
179
// / protocol), follow it from the conforming type.
175
180
Type getAssociatedType (Type origType, Type dependentType) const ;
Original file line number Diff line number Diff line change @@ -194,6 +194,47 @@ ProtocolConformanceRef::getConditionalRequirements() const {
194
194
return {};
195
195
}
196
196
197
+ Type ProtocolConformanceRef::getTypeWitness (Type conformingType,
198
+ AssociatedTypeDecl *assocType,
199
+ SubstOptions options) const {
200
+ if (isPack ()) {
201
+ auto *pack = getPack ();
202
+ ASSERT (conformingType->isEqual (pack->getType ()));
203
+ return pack->getAssociatedType (assocType->getDeclaredInterfaceType ());
204
+ }
205
+
206
+ auto failed = [&]() {
207
+ return DependentMemberType::get (ErrorType::get (conformingType),
208
+ assocType);
209
+ };
210
+
211
+ if (isInvalid ())
212
+ return failed ();
213
+
214
+ auto proto = getRequirement ();
215
+ ASSERT (assocType->getProtocol () == proto);
216
+
217
+ if (isConcrete ()) {
218
+ auto witnessType = getConcrete ()->getTypeWitness (assocType, options);
219
+ if (!witnessType || witnessType->is <ErrorType>())
220
+ return failed ();
221
+ return witnessType;
222
+ }
223
+
224
+ ASSERT (isAbstract ());
225
+
226
+ if (auto *archetypeType = conformingType->getAs <ArchetypeType>()) {
227
+ return archetypeType->getNestedType (assocType);
228
+ }
229
+
230
+ CONDITIONAL_ASSERT (conformingType->isTypeParameter () ||
231
+ conformingType->isTypeVariableOrMember () ||
232
+ conformingType->is <UnresolvedType>() ||
233
+ conformingType->is <PlaceholderType>());
234
+
235
+ return DependentMemberType::get (conformingType, assocType);
236
+ }
237
+
197
238
Type ProtocolConformanceRef::getAssociatedType (Type conformingType,
198
239
Type assocType) const {
199
240
if (isPack ()) {
You can’t perform that action at this time.
0 commit comments