AST: Allow ModuleDecl::lookupConformance() to construct PackConformances for PackTypes

This commit is contained in:
Slava Pestov
2022-08-18 22:27:11 -04:00
parent 1edb9a4ca9
commit 70b553bcdc

View File

@@ -32,6 +32,7 @@
#include "swift/AST/ModuleLoader.h"
#include "swift/AST/NameLookup.h"
#include "swift/AST/NameLookupRequests.h"
#include "swift/AST/PackConformance.h"
#include "swift/AST/ParseRequests.h"
#include "swift/AST/PrettyStackTrace.h"
#include "swift/AST/PrintOptions.h"
@@ -1259,6 +1260,33 @@ static ProtocolConformanceRef getBuiltinBuiltinTypeConformance(
return ProtocolConformanceRef::forMissingOrInvalid(type, protocol);
}
static ProtocolConformanceRef getPackTypeConformance(
PackType *type, ProtocolDecl *protocol, ModuleDecl *mod) {
SmallVector<ProtocolConformanceRef, 2> patternConformances;
for (auto packElement : type->getElementTypes()) {
if (auto *packExpansion = packElement->getAs<PackExpansionType>()) {
auto patternType = packExpansion->getPatternType();
auto patternConformance =
(patternType->isTypeParameter()
? ProtocolConformanceRef(protocol)
: mod->lookupConformance(patternType, protocol));
patternConformances.push_back(patternConformance);
continue;
}
auto patternConformance =
(packElement->isTypeParameter()
? ProtocolConformanceRef(protocol)
: mod->lookupConformance(packElement, protocol));
patternConformances.push_back(patternConformance);
}
return ProtocolConformanceRef(
PackConformance::get(type, protocol, patternConformances));
}
ProtocolConformanceRef
LookupConformanceInModuleRequest::evaluate(
Evaluator &evaluator, LookupConformanceDescriptor desc) const {
@@ -1322,6 +1350,11 @@ LookupConformanceInModuleRequest::evaluate(
if (type->is<UnresolvedType>() || type->is<PlaceholderType>())
return ProtocolConformanceRef(protocol);
// Pack types can conform to protocols.
if (auto packType = type->getAs<PackType>()) {
return getPackTypeConformance(packType, protocol, mod);
}
// Tuple types can conform to protocols.
if (auto tupleType = type->getAs<TupleType>()) {
return getBuiltinTupleTypeConformance(type, tupleType, protocol, mod);