mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Simplify the interface to Module::lookupConformance.
Rather than returning a weird PointerIntPair, return an Optional<ProtocolConformanceRef>. NFC
This commit is contained in:
@@ -739,23 +739,17 @@ ArrayRef<Substitution> BoundGenericType::getSubstitutions(
|
||||
|
||||
SmallVector<ProtocolConformanceRef, 4> conformances;
|
||||
for (auto proto : archetype->getConformsTo()) {
|
||||
// If the type is a type variable or is dependent, just fill in null
|
||||
// If the type is a type variable or is dependent, just fill in empty
|
||||
// conformances.
|
||||
if (type->is<TypeVariableType>() || type->isTypeParameter()) {
|
||||
conformances.push_back(ProtocolConformanceRef(proto));
|
||||
|
||||
// Otherwise, find the conformances.
|
||||
} else {
|
||||
auto conforms = module->lookupConformance(type, proto, resolver);
|
||||
switch (conforms.getInt()) {
|
||||
case ConformanceKind::Conforms:
|
||||
conformances.push_back(
|
||||
ProtocolConformanceRef(proto, conforms.getPointer()));
|
||||
break;
|
||||
case ConformanceKind::DoesNotConform:
|
||||
if (auto conforms = module->lookupConformance(type, proto, resolver))
|
||||
conformances.push_back(*conforms);
|
||||
else
|
||||
conformances.push_back(ProtocolConformanceRef(proto));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -778,9 +772,9 @@ ArrayRef<Substitution> BoundGenericType::getSubstitutions(
|
||||
return permanentSubs;
|
||||
}
|
||||
|
||||
LookupConformanceResult Module::lookupConformance(Type type,
|
||||
ProtocolDecl *protocol,
|
||||
LazyResolver *resolver) {
|
||||
Optional<ProtocolConformanceRef>
|
||||
Module::lookupConformance(Type type, ProtocolDecl *protocol,
|
||||
LazyResolver *resolver) {
|
||||
ASTContext &ctx = getASTContext();
|
||||
|
||||
// An archetype conforms to a protocol if the protocol is listed in the
|
||||
@@ -788,18 +782,18 @@ LookupConformanceResult Module::lookupConformance(Type type,
|
||||
if (auto archetype = type->getAs<ArchetypeType>()) {
|
||||
if (protocol->isSpecificProtocol(KnownProtocolKind::AnyObject)) {
|
||||
if (archetype->requiresClass())
|
||||
return { nullptr, ConformanceKind::Conforms };
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
return ProtocolConformanceRef(protocol);
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
for (auto ap : archetype->getConformsTo()) {
|
||||
if (ap == protocol || ap->inheritsFrom(protocol))
|
||||
return { nullptr, ConformanceKind::Conforms };
|
||||
return ProtocolConformanceRef(protocol);
|
||||
}
|
||||
|
||||
if (!archetype->getSuperclass()) {
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
}
|
||||
if (!archetype->getSuperclass())
|
||||
return None;
|
||||
}
|
||||
|
||||
// An existential conforms to a protocol if the protocol is listed in the
|
||||
@@ -815,46 +809,46 @@ LookupConformanceResult Module::lookupConformance(Type type,
|
||||
for (auto proto : protocols) {
|
||||
if (!proto->isObjC() &&
|
||||
!proto->isSpecificProtocol(KnownProtocolKind::AnyObject))
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
return None;
|
||||
}
|
||||
|
||||
// If the existential type cannot be represented or the protocol does not
|
||||
// conform to itself, there's no point in looking further.
|
||||
if (!protocol->existentialConformsToSelf() ||
|
||||
!protocol->existentialTypeSupported(resolver))
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
return None;
|
||||
|
||||
// Special-case AnyObject, which may not be in the list of conformances.
|
||||
if (protocol->isSpecificProtocol(KnownProtocolKind::AnyObject)) {
|
||||
return { nullptr, type->isClassExistentialType()
|
||||
? ConformanceKind::Conforms
|
||||
: ConformanceKind::DoesNotConform };
|
||||
if (type->isClassExistentialType())
|
||||
return ProtocolConformanceRef(protocol);
|
||||
|
||||
return None;
|
||||
}
|
||||
|
||||
// Look for this protocol within the existential's list of conformances.
|
||||
for (auto proto : protocols) {
|
||||
if (proto == protocol || proto->inheritsFrom(protocol)) {
|
||||
return { nullptr, ConformanceKind::Conforms };
|
||||
}
|
||||
if (proto == protocol || proto->inheritsFrom(protocol))
|
||||
return ProtocolConformanceRef(protocol);
|
||||
}
|
||||
|
||||
// We didn't find our protocol in the existential's list; it doesn't
|
||||
// conform.
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
return None;
|
||||
}
|
||||
|
||||
// Check for protocol conformance of archetype via superclass requirement.
|
||||
if (auto archetype = type->getAs<ArchetypeType>()) {
|
||||
if (auto super = archetype->getSuperclass()) {
|
||||
auto inheritedConformance = lookupConformance(super, protocol, resolver);
|
||||
switch (inheritedConformance.getInt()) {
|
||||
case ConformanceKind::DoesNotConform:
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
case ConformanceKind::Conforms:
|
||||
auto result =
|
||||
ctx.getInheritedConformance(type, inheritedConformance.getPointer());
|
||||
return { result, ConformanceKind::Conforms };
|
||||
if (auto inheritedConformance = lookupConformance(super, protocol,
|
||||
resolver)) {
|
||||
return ProtocolConformanceRef(
|
||||
ctx.getInheritedConformance(
|
||||
type,
|
||||
inheritedConformance->getConcrete()));
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -862,27 +856,21 @@ LookupConformanceResult Module::lookupConformance(Type type,
|
||||
// diagnostics. We consider it to conform to all protocols, since the
|
||||
// intended type might have.
|
||||
if (type->is<UnresolvedType>()) {
|
||||
return {
|
||||
ctx.getConformance(type, protocol, protocol->getLoc(), this,
|
||||
ProtocolConformanceState::Complete),
|
||||
ConformanceKind::Conforms
|
||||
};
|
||||
return ProtocolConformanceRef(
|
||||
ctx.getConformance(type, protocol, protocol->getLoc(), this,
|
||||
ProtocolConformanceState::Complete));
|
||||
}
|
||||
|
||||
|
||||
auto nominal = type->getAnyNominal();
|
||||
|
||||
// If we don't have a nominal type, there are no conformances.
|
||||
// FIXME: We may have implicit conformances for some cases. Handle those
|
||||
// here.
|
||||
if (!nominal) {
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
}
|
||||
if (!nominal) return None;
|
||||
|
||||
// Find the (unspecialized) conformance.
|
||||
SmallVector<ProtocolConformance *, 2> conformances;
|
||||
if (!nominal->lookupConformance(this, protocol, conformances))
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
return None;
|
||||
|
||||
// FIXME: Ambiguity resolution.
|
||||
auto conformance = conformances.front();
|
||||
@@ -905,19 +893,13 @@ LookupConformanceResult Module::lookupConformance(Type type,
|
||||
// Compute the conformance for the inherited type.
|
||||
auto inheritedConformance = lookupConformance(superclassTy, protocol,
|
||||
resolver);
|
||||
switch (inheritedConformance.getInt()) {
|
||||
case ConformanceKind::DoesNotConform:
|
||||
llvm_unreachable("We already found the inherited conformance");
|
||||
|
||||
case ConformanceKind::Conforms:
|
||||
// Create inherited conformance below.
|
||||
break;
|
||||
}
|
||||
assert(inheritedConformance &&
|
||||
"We already found the inherited conformance");
|
||||
|
||||
// Create the inherited conformance entry.
|
||||
conformance
|
||||
= ctx.getInheritedConformance(type, inheritedConformance.getPointer());
|
||||
return { conformance, ConformanceKind::Conforms };
|
||||
= ctx.getInheritedConformance(type, inheritedConformance->getConcrete());
|
||||
return ProtocolConformanceRef(conformance);
|
||||
}
|
||||
|
||||
// If the type is specialized, find the conformance for the generic type.
|
||||
@@ -938,18 +920,18 @@ LookupConformanceResult Module::lookupConformance(Type type,
|
||||
|
||||
for (auto sub : substitutions) {
|
||||
if (sub.getReplacement()->is<ErrorType>())
|
||||
return { nullptr, ConformanceKind::DoesNotConform };
|
||||
return None;
|
||||
}
|
||||
|
||||
// Create the specialized conformance entry.
|
||||
auto result = ctx.getSpecializedConformance(type, conformance,
|
||||
substitutions);
|
||||
return { result, ConformanceKind::Conforms };
|
||||
return ProtocolConformanceRef(result);
|
||||
}
|
||||
}
|
||||
|
||||
// Record and return the simple conformance.
|
||||
return { conformance, ConformanceKind::Conforms };
|
||||
return ProtocolConformanceRef(conformance);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
Reference in New Issue
Block a user