AST: Allow ProtocolConformanceRef::getAssociatedType() with invalid conformance

This commit is contained in:
Slava Pestov
2024-09-18 11:20:45 -04:00
parent 532e048abb
commit a8ed7ba61d

View File

@@ -198,28 +198,40 @@ Type ProtocolConformanceRef::getAssociatedType(Type conformingType,
Type assocType) const { Type assocType) const {
if (isPack()) { if (isPack()) {
auto *pack = getPack(); auto *pack = getPack();
assert(conformingType->isEqual(pack->getType())); ASSERT(conformingType->isEqual(pack->getType()));
return pack->getAssociatedType(assocType); return pack->getAssociatedType(assocType);
} }
assert(!isConcrete() || getConcrete()->getType()->isEqual(conformingType));
auto type = assocType->getCanonicalType(); auto type = assocType->getCanonicalType();
auto proto = getRequirement();
// Fast path for generic parameters. // Fast path for generic parameters.
if (isa<GenericTypeParamType>(type)) { if (auto paramTy = dyn_cast<GenericTypeParamType>(type)) {
assert(type->isEqual(proto->getSelfInterfaceType()) && ASSERT(paramTy->getDepth() == 0 && paramTy->getIndex() == 0 &&
"type parameter in protocol was not Self"); "type parameter in protocol was not Self");
return conformingType; return conformingType;
} }
// Fast path for dependent member types on 'Self' of our associated types. if (isInvalid())
auto memberType = cast<DependentMemberType>(type); return ErrorType::get(assocType->getASTContext());
if (memberType.getBase()->isEqual(proto->getSelfInterfaceType()) &&
memberType->getAssocType()->getProtocol() == proto && auto proto = getRequirement();
isConcrete())
return getConcrete()->getTypeWitness(memberType->getAssocType()); if (isConcrete()) {
if (auto selfType = conformingType->getAs<DynamicSelfType>())
conformingType = selfType->getSelfType();
ASSERT(getConcrete()->getType()->isEqual(conformingType));
// Fast path for dependent member types on 'Self' of our associated types.
auto memberType = cast<DependentMemberType>(type);
if (memberType.getBase()->isEqual(proto->getSelfInterfaceType()) &&
memberType->getAssocType()->getProtocol() == proto) {
auto witnessType = getConcrete()->getTypeWitness(
memberType->getAssocType());
if (!witnessType)
return ErrorType::get(assocType->getASTContext());
return witnessType;
}
}
// General case: consult the substitution map. // General case: consult the substitution map.
auto substMap = auto substMap =