|
2 | 2 | //
|
3 | 3 | // This source file is part of the Swift.org open source project
|
4 | 4 | //
|
5 |
| -// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| 5 | +// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors |
6 | 6 | // Licensed under Apache License v2.0 with Runtime Library Exception
|
7 | 7 | //
|
8 | 8 | // See https://swift.org/LICENSE.txt for license information
|
@@ -66,7 +66,10 @@ enum class ProtocolConformanceKind {
|
66 | 66 | Specialized,
|
67 | 67 | /// Conformance of a generic class type projected through one of its
|
68 | 68 | /// superclass's conformances.
|
69 |
| - Inherited |
| 69 | + Inherited, |
| 70 | + /// Builtin conformances are special conformaces that the runtime handles |
| 71 | + /// and isn't implemented directly in Swift. |
| 72 | + Builtin |
70 | 73 | };
|
71 | 74 |
|
72 | 75 | /// Describes the state of a protocol conformance, which may be complete,
|
@@ -329,7 +332,9 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
|
329 | 332 | /// - the type is directly declared to conform to the protocol (a
|
330 | 333 | /// normal conformance) or
|
331 | 334 | /// - the protocol's existential type is known to conform to itself (a
|
332 |
| -/// self-conformance). |
| 335 | +/// self-conformance) or |
| 336 | +/// - the type's conformance is declared within the runtime (a builtin |
| 337 | +/// conformance). |
333 | 338 | class RootProtocolConformance : public ProtocolConformance {
|
334 | 339 | protected:
|
335 | 340 | RootProtocolConformance(ProtocolConformanceKind kind, Type conformingType)
|
@@ -380,7 +385,8 @@ class RootProtocolConformance : public ProtocolConformance {
|
380 | 385 |
|
381 | 386 | static bool classof(const ProtocolConformance *conformance) {
|
382 | 387 | return conformance->getKind() == ProtocolConformanceKind::Normal ||
|
383 |
| - conformance->getKind() == ProtocolConformanceKind::Self; |
| 388 | + conformance->getKind() == ProtocolConformanceKind::Self || |
| 389 | + conformance->getKind() == ProtocolConformanceKind::Builtin; |
384 | 390 | }
|
385 | 391 | };
|
386 | 392 |
|
@@ -1014,6 +1020,110 @@ class InheritedProtocolConformance : public ProtocolConformance,
|
1014 | 1020 | }
|
1015 | 1021 | };
|
1016 | 1022 |
|
| 1023 | +/// A builtin conformance appears when a special non-nominal type has a runtime |
| 1024 | +/// declared conformance. E.g. the runtime implements Equatable for tuples. |
| 1025 | +class BuiltinProtocolConformance final : public RootProtocolConformance, |
| 1026 | + private llvm::TrailingObjects<BuiltinProtocolConformance, |
| 1027 | + ProtocolConformanceRef> { |
| 1028 | + friend ASTContext; |
| 1029 | + friend TrailingObjects; |
| 1030 | + |
| 1031 | + ProtocolDecl *protocol = nullptr; |
| 1032 | + size_t numConformances; |
| 1033 | + |
| 1034 | + mutable Optional<ArrayRef<Requirement>> conditionalConformances = None; |
| 1035 | + |
| 1036 | + BuiltinProtocolConformance(Type conformingType, ProtocolDecl *protocol, |
| 1037 | + ArrayRef<ProtocolConformanceRef> conformances); |
| 1038 | + |
| 1039 | + size_t numTrailingObjects(OverloadToken<ProtocolConformanceRef>) const { |
| 1040 | + return numConformances; |
| 1041 | + } |
| 1042 | + |
| 1043 | +public: |
| 1044 | + /// Get the protocol being conformed to. |
| 1045 | + ProtocolDecl *getProtocol() const { |
| 1046 | + return protocol; |
| 1047 | + } |
| 1048 | + |
| 1049 | + /// Get the trailing conformances that this builtin conformance needs. |
| 1050 | + MutableArrayRef<ProtocolConformanceRef> getConformances() { |
| 1051 | + return {getTrailingObjects<ProtocolConformanceRef>(), numConformances}; |
| 1052 | + } |
| 1053 | + |
| 1054 | + /// Get the trailing conformances that this builtin conformance needs. |
| 1055 | + ArrayRef<ProtocolConformanceRef> getConformances() const { |
| 1056 | + return {getTrailingObjects<ProtocolConformanceRef>(), numConformances}; |
| 1057 | + } |
| 1058 | + |
| 1059 | + /// Get any requirements that must be satisfied for this conformance to apply. |
| 1060 | + Optional<ArrayRef<Requirement>> |
| 1061 | + getConditionalRequirementsIfAvailable() const { |
| 1062 | + return ArrayRef<Requirement>(); |
| 1063 | + } |
| 1064 | + |
| 1065 | + /// Get any requirements that must be satisfied for this conformance to apply. |
| 1066 | + ArrayRef<Requirement> getConditionalRequirements() const; |
| 1067 | + |
| 1068 | + /// Get the declaration context that contains the nominal type declaration. |
| 1069 | + DeclContext *getDeclContext() const { |
| 1070 | + return getProtocol(); |
| 1071 | + } |
| 1072 | + |
| 1073 | + /// Retrieve the state of this conformance. |
| 1074 | + ProtocolConformanceState getState() const { |
| 1075 | + return ProtocolConformanceState::Complete; |
| 1076 | + } |
| 1077 | + |
| 1078 | + /// Get the kind of source from which this conformance comes. |
| 1079 | + ConformanceEntryKind getSourceKind() const { |
| 1080 | + return ConformanceEntryKind::Synthesized; |
| 1081 | + } |
| 1082 | + /// Get the protocol conformance which implied this implied conformance. |
| 1083 | + NormalProtocolConformance *getImplyingConformance() const { |
| 1084 | + return nullptr; |
| 1085 | + } |
| 1086 | + |
| 1087 | + bool hasTypeWitness(AssociatedTypeDecl *assocType) const { |
| 1088 | + llvm_unreachable("builtin-conformances currently don't have associated \ |
| 1089 | + types"); |
| 1090 | + } |
| 1091 | + |
| 1092 | + /// Retrieve the type witness and type decl (if one exists) |
| 1093 | + /// for the given associated type. |
| 1094 | + TypeWitnessAndDecl |
| 1095 | + getTypeWitnessAndDecl(AssociatedTypeDecl *assocType, |
| 1096 | + SubstOptions options=None) const { |
| 1097 | + llvm_unreachable("builtin-conformances currently don't have associated \ |
| 1098 | + types"); |
| 1099 | + } |
| 1100 | + |
| 1101 | + /// Given that the requirement signature of the protocol directly states |
| 1102 | + /// that the given dependent type must conform to the given protocol, |
| 1103 | + /// return its associated conformance. |
| 1104 | + ProtocolConformanceRef |
| 1105 | + getAssociatedConformance(Type assocType, ProtocolDecl *protocol) const { |
| 1106 | + llvm_unreachable("builtin-conformances currently don't have associated \ |
| 1107 | + types"); |
| 1108 | + } |
| 1109 | + |
| 1110 | + /// Retrieve the witness corresponding to the given value requirement. |
| 1111 | + ConcreteDeclRef getWitnessDeclRef(ValueDecl *requirement) const { |
| 1112 | + return ConcreteDeclRef(requirement); |
| 1113 | + } |
| 1114 | + |
| 1115 | + /// Determine whether the witness for the given requirement |
| 1116 | + /// is either the default definition or was otherwise deduced. |
| 1117 | + bool usesDefaultDefinition(AssociatedTypeDecl *requirement) const { |
| 1118 | + llvm_unreachable("builtin-conformances currently don't have associated \ |
| 1119 | + types"); |
| 1120 | + } |
| 1121 | + |
| 1122 | + static bool classof(const ProtocolConformance *conformance) { |
| 1123 | + return conformance->getKind() == ProtocolConformanceKind::Builtin; |
| 1124 | + } |
| 1125 | +}; |
| 1126 | + |
1017 | 1127 | inline bool ProtocolConformance::isInvalid() const {
|
1018 | 1128 | return getRootConformance()->isInvalid();
|
1019 | 1129 | }
|
|
0 commit comments