Skip to content

Commit e08e525

Browse files
committed
AST: Split off ProtocolConformanceRef.cpp from ProtocolConformance.cpp
1 parent 3992b18 commit e08e525

File tree

3 files changed

+307
-282
lines changed

3 files changed

+307
-282
lines changed

lib/AST/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ add_swift_host_library(swiftAST STATIC
7474
PlatformKind.cpp
7575
PrettyStackTrace.cpp
7676
ProtocolConformance.cpp
77+
ProtocolConformanceRef.cpp
7778
RawComment.cpp
7879
RequirementEnvironment.cpp
7980
RequirementMachine/ConcreteContraction.cpp

lib/AST/ProtocolConformance.cpp

Lines changed: 1 addition & 282 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212
//
13-
// This file implements the protocol conformance data structures.
13+
// This file implements the ProtocolConformance class hierarchy.
1414
//
1515
//===----------------------------------------------------------------------===//
1616

@@ -25,13 +25,9 @@
2525
#include "swift/AST/LazyResolver.h"
2626
#include "swift/AST/Module.h"
2727
#include "swift/AST/TypeCheckRequests.h"
28-
#include "swift/AST/TypeWalker.h"
2928
#include "swift/AST/Types.h"
30-
#include "swift/AST/TypeCheckRequests.h"
3129
#include "swift/Basic/Statistic.h"
32-
#include "llvm/ADT/MapVector.h"
3330
#include "llvm/ADT/Statistic.h"
34-
#include "llvm/ADT/TinyPtrVector.h"
3531
#include "llvm/Support/PrettyStackTrace.h"
3632
#include "llvm/Support/SaveAndRestore.h"
3733

@@ -79,128 +75,6 @@ void Witness::dump(llvm::raw_ostream &out) const {
7975
}
8076
}
8177

82-
ProtocolConformanceRef::ProtocolConformanceRef(ProtocolDecl *protocol,
83-
ProtocolConformance *conf) {
84-
assert(protocol != nullptr &&
85-
"cannot construct ProtocolConformanceRef with null protocol");
86-
if (conf) {
87-
assert(protocol == conf->getProtocol() && "protocol conformance mismatch");
88-
Union = conf;
89-
} else {
90-
Union = protocol;
91-
}
92-
}
93-
94-
ProtocolDecl *ProtocolConformanceRef::getRequirement() const {
95-
assert(!isInvalid());
96-
97-
if (isConcrete()) {
98-
return getConcrete()->getProtocol();
99-
} else {
100-
return getAbstract();
101-
}
102-
}
103-
104-
ProtocolConformanceRef
105-
ProtocolConformanceRef::subst(Type origType,
106-
SubstitutionMap subMap,
107-
SubstOptions options) const {
108-
return subst(origType,
109-
QuerySubstitutionMap{subMap},
110-
LookUpConformanceInSubstitutionMap(subMap),
111-
options);
112-
}
113-
114-
ProtocolConformanceRef
115-
ProtocolConformanceRef::subst(Type origType,
116-
TypeSubstitutionFn subs,
117-
LookupConformanceFn conformances,
118-
SubstOptions options) const {
119-
if (isInvalid())
120-
return *this;
121-
122-
// If we have a concrete conformance, we need to substitute the
123-
// conformance to apply to the new type.
124-
if (isConcrete())
125-
return ProtocolConformanceRef(getConcrete()->subst(subs, conformances,
126-
options));
127-
// If the type is an opaque archetype, the conformance will remain abstract,
128-
// unless we're specifically substituting opaque types.
129-
if (auto origArchetype = origType->getAs<ArchetypeType>()) {
130-
if (!options.contains(SubstFlags::SubstituteOpaqueArchetypes)
131-
&& isa<OpaqueTypeArchetypeType>(origArchetype)) {
132-
return *this;
133-
}
134-
}
135-
136-
// Otherwise, compute the substituted type.
137-
auto substType = origType.subst(subs, conformances, options);
138-
139-
auto *proto = getRequirement();
140-
141-
// If the type is an existential, it must be self-conforming.
142-
if (substType->isExistentialType()) {
143-
auto optConformance =
144-
proto->getModuleContext()->lookupExistentialConformance(substType,
145-
proto);
146-
if (optConformance)
147-
return optConformance;
148-
149-
return ProtocolConformanceRef::forInvalid();
150-
}
151-
152-
// Check the conformance map.
153-
return conformances(origType->getCanonicalType(), substType, proto);
154-
}
155-
156-
ProtocolConformanceRef ProtocolConformanceRef::mapConformanceOutOfContext() const {
157-
if (!isConcrete())
158-
return *this;
159-
160-
auto *concrete = getConcrete()->subst(
161-
[](SubstitutableType *type) -> Type {
162-
if (auto *archetypeType = type->getAs<ArchetypeType>())
163-
return archetypeType->getInterfaceType();
164-
return type;
165-
},
166-
MakeAbstractConformanceForGenericType());
167-
return ProtocolConformanceRef(concrete);
168-
}
169-
170-
Type
171-
ProtocolConformanceRef::getTypeWitnessByName(Type type, Identifier name) const {
172-
assert(!isInvalid());
173-
174-
// Find the named requirement.
175-
ProtocolDecl *proto = getRequirement();
176-
auto *assocType = proto->getAssociatedType(name);
177-
178-
// FIXME: Shouldn't this be a hard error?
179-
if (!assocType)
180-
return ErrorType::get(proto->getASTContext());
181-
182-
return assocType->getDeclaredInterfaceType().subst(
183-
SubstitutionMap::getProtocolSubstitutions(proto, type, *this));
184-
}
185-
186-
ConcreteDeclRef
187-
ProtocolConformanceRef::getWitnessByName(Type type, DeclName name) const {
188-
// Find the named requirement.
189-
auto *proto = getRequirement();
190-
auto *requirement = proto->getSingleRequirement(name);
191-
if (requirement == nullptr)
192-
return ConcreteDeclRef();
193-
194-
// For a type with dependent conformance, just return the requirement from
195-
// the protocol. There are no protocol conformance tables.
196-
if (!isConcrete()) {
197-
auto subs = SubstitutionMap::getProtocolSubstitutions(proto, type, *this);
198-
return ConcreteDeclRef(requirement, subs);
199-
}
200-
201-
return getConcrete()->getWitnessDeclRef(requirement);
202-
}
203-
20478
#define CONFORMANCE_SUBCLASS_DISPATCH(Method, Args) \
20579
switch (getKind()) { \
20680
case ProtocolConformanceKind::Normal: \
@@ -455,26 +329,6 @@ ArrayRef<Requirement> ProtocolConformance::getConditionalRequirements() const {
455329
CONFORMANCE_SUBCLASS_DISPATCH(getConditionalRequirements, ());
456330
}
457331

458-
Optional<ArrayRef<Requirement>>
459-
ProtocolConformanceRef::getConditionalRequirementsIfAvailable() const {
460-
if (isConcrete())
461-
return getConcrete()->getConditionalRequirementsIfAvailable();
462-
else
463-
// An abstract conformance is never conditional: any conditionality in the
464-
// concrete types that will eventually pass through this at runtime is
465-
// completely pre-checked and packaged up.
466-
return ArrayRef<Requirement>();
467-
}
468-
469-
ArrayRef<Requirement>
470-
ProtocolConformanceRef::getConditionalRequirements() const {
471-
if (isConcrete())
472-
return getConcrete()->getConditionalRequirements();
473-
else
474-
// An abstract conformance is never conditional, as above.
475-
return {};
476-
}
477-
478332
Optional<ArrayRef<Requirement>>
479333
NormalProtocolConformance::getConditionalRequirementsIfAvailable() const {
480334
const auto &eval = getDeclContext()->getASTContext().evaluator;
@@ -682,54 +536,6 @@ Type ProtocolConformance::getAssociatedType(Type assocType) const {
682536
return ref.getAssociatedType(getType(), assocType);
683537
}
684538

685-
Type ProtocolConformanceRef::getAssociatedType(Type conformingType,
686-
Type assocType) const {
687-
assert(!isConcrete() || getConcrete()->getType()->isEqual(conformingType));
688-
689-
auto type = assocType->getCanonicalType();
690-
auto proto = getRequirement();
691-
692-
// Fast path for generic parameters.
693-
if (isa<GenericTypeParamType>(type)) {
694-
assert(type->isEqual(proto->getSelfInterfaceType()) &&
695-
"type parameter in protocol was not Self");
696-
return conformingType;
697-
}
698-
699-
// Fast path for dependent member types on 'Self' of our associated types.
700-
auto memberType = cast<DependentMemberType>(type);
701-
if (memberType.getBase()->isEqual(proto->getSelfInterfaceType()) &&
702-
memberType->getAssocType()->getProtocol() == proto &&
703-
isConcrete())
704-
return getConcrete()->getTypeWitness(memberType->getAssocType());
705-
706-
// General case: consult the substitution map.
707-
auto substMap =
708-
SubstitutionMap::getProtocolSubstitutions(proto, conformingType, *this);
709-
return type.subst(substMap);
710-
}
711-
712-
ProtocolConformanceRef
713-
ProtocolConformanceRef::getAssociatedConformance(Type conformingType,
714-
Type assocType,
715-
ProtocolDecl *protocol) const {
716-
// If this is a concrete conformance, look up the associated conformance.
717-
if (isConcrete()) {
718-
auto conformance = getConcrete();
719-
assert(conformance->getType()->isEqual(conformingType));
720-
return conformance->getAssociatedConformance(assocType, protocol);
721-
}
722-
723-
// Otherwise, apply the substitution {self -> conformingType}
724-
// to the abstract conformance requirement laid upon the dependent type
725-
// by the protocol.
726-
auto subMap =
727-
SubstitutionMap::getProtocolSubstitutions(getRequirement(),
728-
conformingType, *this);
729-
auto abstractConf = ProtocolConformanceRef(protocol);
730-
return abstractConf.subst(assocType, subMap);
731-
}
732-
733539
ProtocolConformanceRef
734540
ProtocolConformance::getAssociatedConformance(Type assocType,
735541
ProtocolDecl *protocol) const {
@@ -1669,20 +1475,6 @@ ProtocolConformance *ProtocolConformance::getCanonicalConformance() {
16691475
llvm_unreachable("bad ProtocolConformanceKind");
16701476
}
16711477

1672-
/// Check of all types used by the conformance are canonical.
1673-
bool ProtocolConformanceRef::isCanonical() const {
1674-
if (isAbstract() || isInvalid())
1675-
return true;
1676-
return getConcrete()->isCanonical();
1677-
}
1678-
1679-
ProtocolConformanceRef
1680-
ProtocolConformanceRef::getCanonicalConformanceRef() const {
1681-
if (isAbstract() || isInvalid())
1682-
return *this;
1683-
return ProtocolConformanceRef(getConcrete()->getCanonicalConformance());
1684-
}
1685-
16861478
BuiltinProtocolConformance::BuiltinProtocolConformance(
16871479
Type conformingType, ProtocolDecl *protocol,
16881480
GenericSignature genericSig,
@@ -1742,76 +1534,3 @@ void swift::simple_display(llvm::raw_ostream &out,
17421534
SourceLoc swift::extractNearestSourceLoc(const ProtocolConformance *conformance) {
17431535
return extractNearestSourceLoc(conformance->getDeclContext());
17441536
}
1745-
1746-
void swift::simple_display(llvm::raw_ostream &out, ProtocolConformanceRef conformanceRef) {
1747-
if (conformanceRef.isAbstract()) {
1748-
simple_display(out, conformanceRef.getAbstract());
1749-
} else if (conformanceRef.isConcrete()) {
1750-
simple_display(out, conformanceRef.getConcrete());
1751-
}
1752-
}
1753-
1754-
SourceLoc swift::extractNearestSourceLoc(const ProtocolConformanceRef conformanceRef) {
1755-
if (conformanceRef.isAbstract()) {
1756-
return extractNearestSourceLoc(conformanceRef.getAbstract());
1757-
} else if (conformanceRef.isConcrete()) {
1758-
return extractNearestSourceLoc(conformanceRef.getConcrete());
1759-
}
1760-
return SourceLoc();
1761-
}
1762-
1763-
bool ProtocolConformanceRef::hasUnavailableConformance() const {
1764-
if (isInvalid())
1765-
return false;
1766-
1767-
// Abstract conformances are never unavailable.
1768-
if (!isConcrete())
1769-
return false;
1770-
1771-
// Check whether this conformance is on an unavailable extension.
1772-
auto concrete = getConcrete();
1773-
auto ext = dyn_cast<ExtensionDecl>(concrete->getDeclContext());
1774-
if (ext && AvailableAttr::isUnavailable(ext))
1775-
return true;
1776-
1777-
// Check the conformances in the substitution map.
1778-
auto module = concrete->getDeclContext()->getParentModule();
1779-
auto subMap = concrete->getSubstitutions(module);
1780-
for (auto subConformance : subMap.getConformances()) {
1781-
if (subConformance.hasUnavailableConformance())
1782-
return true;
1783-
}
1784-
1785-
return false;
1786-
}
1787-
1788-
bool ProtocolConformanceRef::hasMissingConformance(ModuleDecl *module) const {
1789-
return forEachMissingConformance(module,
1790-
[](BuiltinProtocolConformance *builtin) {
1791-
return true;
1792-
});
1793-
}
1794-
1795-
bool ProtocolConformanceRef::forEachMissingConformance(
1796-
ModuleDecl *module,
1797-
llvm::function_ref<bool(BuiltinProtocolConformance *missing)> fn) const {
1798-
if (!isConcrete())
1799-
return false;
1800-
1801-
// Is this a missing conformance?
1802-
ProtocolConformance *concreteConf = getConcrete();
1803-
RootProtocolConformance *rootConf = concreteConf->getRootConformance();
1804-
if (auto builtinConformance = dyn_cast<BuiltinProtocolConformance>(rootConf)){
1805-
if (builtinConformance->isMissing() && fn(builtinConformance))
1806-
return true;
1807-
}
1808-
1809-
// Check conformances that are part of this conformance.
1810-
auto subMap = concreteConf->getSubstitutions(module);
1811-
for (auto conformance : subMap.getConformances()) {
1812-
if (conformance.forEachMissingConformance(module, fn))
1813-
return true;
1814-
}
1815-
1816-
return false;
1817-
}

0 commit comments

Comments
 (0)