|
10 | 10 | //
|
11 | 11 | //===----------------------------------------------------------------------===//
|
12 | 12 | //
|
13 |
| -// This file implements the protocol conformance data structures. |
| 13 | +// This file implements the ProtocolConformance class hierarchy. |
14 | 14 | //
|
15 | 15 | //===----------------------------------------------------------------------===//
|
16 | 16 |
|
|
25 | 25 | #include "swift/AST/LazyResolver.h"
|
26 | 26 | #include "swift/AST/Module.h"
|
27 | 27 | #include "swift/AST/TypeCheckRequests.h"
|
28 |
| -#include "swift/AST/TypeWalker.h" |
29 | 28 | #include "swift/AST/Types.h"
|
30 |
| -#include "swift/AST/TypeCheckRequests.h" |
31 | 29 | #include "swift/Basic/Statistic.h"
|
32 |
| -#include "llvm/ADT/MapVector.h" |
33 | 30 | #include "llvm/ADT/Statistic.h"
|
34 |
| -#include "llvm/ADT/TinyPtrVector.h" |
35 | 31 | #include "llvm/Support/PrettyStackTrace.h"
|
36 | 32 | #include "llvm/Support/SaveAndRestore.h"
|
37 | 33 |
|
@@ -79,128 +75,6 @@ void Witness::dump(llvm::raw_ostream &out) const {
|
79 | 75 | }
|
80 | 76 | }
|
81 | 77 |
|
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 |
| - |
204 | 78 | #define CONFORMANCE_SUBCLASS_DISPATCH(Method, Args) \
|
205 | 79 | switch (getKind()) { \
|
206 | 80 | case ProtocolConformanceKind::Normal: \
|
@@ -455,26 +329,6 @@ ArrayRef<Requirement> ProtocolConformance::getConditionalRequirements() const {
|
455 | 329 | CONFORMANCE_SUBCLASS_DISPATCH(getConditionalRequirements, ());
|
456 | 330 | }
|
457 | 331 |
|
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 |
| - |
478 | 332 | Optional<ArrayRef<Requirement>>
|
479 | 333 | NormalProtocolConformance::getConditionalRequirementsIfAvailable() const {
|
480 | 334 | const auto &eval = getDeclContext()->getASTContext().evaluator;
|
@@ -682,54 +536,6 @@ Type ProtocolConformance::getAssociatedType(Type assocType) const {
|
682 | 536 | return ref.getAssociatedType(getType(), assocType);
|
683 | 537 | }
|
684 | 538 |
|
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 |
| - |
733 | 539 | ProtocolConformanceRef
|
734 | 540 | ProtocolConformance::getAssociatedConformance(Type assocType,
|
735 | 541 | ProtocolDecl *protocol) const {
|
@@ -1669,20 +1475,6 @@ ProtocolConformance *ProtocolConformance::getCanonicalConformance() {
|
1669 | 1475 | llvm_unreachable("bad ProtocolConformanceKind");
|
1670 | 1476 | }
|
1671 | 1477 |
|
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 |
| - |
1686 | 1478 | BuiltinProtocolConformance::BuiltinProtocolConformance(
|
1687 | 1479 | Type conformingType, ProtocolDecl *protocol,
|
1688 | 1480 | GenericSignature genericSig,
|
@@ -1742,76 +1534,3 @@ void swift::simple_display(llvm::raw_ostream &out,
|
1742 | 1534 | SourceLoc swift::extractNearestSourceLoc(const ProtocolConformance *conformance) {
|
1743 | 1535 | return extractNearestSourceLoc(conformance->getDeclContext());
|
1744 | 1536 | }
|
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