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 {
170170 // / Map contextual types to interface types in the conformance.
171171 ProtocolConformanceRef mapConformanceOutOfContext () const ;
172172
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+
173178 // / Given a dependent type (expressed in terms of this conformance's
174179 // / protocol), follow it from the conforming type.
175180 Type getAssociatedType (Type origType, Type dependentType) const ;
Original file line number Diff line number Diff line change @@ -194,6 +194,47 @@ ProtocolConformanceRef::getConditionalRequirements() const {
194194 return {};
195195}
196196
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+
197238Type ProtocolConformanceRef::getAssociatedType (Type conformingType,
198239 Type assocType) const {
199240 if (isPack ()) {
You can’t perform that action at this time.
0 commit comments