Skip to content

Commit 508dacc

Browse files
committed
AST: Add ProtocolConformanceRef::getTypeWitness()
1 parent a27d6cf commit 508dacc

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

include/swift/AST/ProtocolConformanceRef.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff 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;

lib/AST/ProtocolConformanceRef.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff 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+
197238
Type ProtocolConformanceRef::getAssociatedType(Type conformingType,
198239
Type assocType) const {
199240
if (isPack()) {

0 commit comments

Comments
 (0)