|
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 |
|
@@ -987,6 +993,103 @@ class InheritedProtocolConformance : public ProtocolConformance,
|
987 | 993 | }
|
988 | 994 | };
|
989 | 995 |
|
| 996 | +/// A builtin conformance appears when a non-nominal type has a |
| 997 | +/// conformance that is synthesized by the implementation. |
| 998 | +class BuiltinProtocolConformance final : public RootProtocolConformance, |
| 999 | + private llvm::TrailingObjects<BuiltinProtocolConformance, Requirement> { |
| 1000 | + friend ASTContext; |
| 1001 | + friend TrailingObjects; |
| 1002 | + |
| 1003 | + ProtocolDecl *protocol; |
| 1004 | + GenericSignature genericSig; |
| 1005 | + size_t numConditionalRequirements; |
| 1006 | + |
| 1007 | + size_t numTrailingObjects(OverloadToken<Requirement>) const { |
| 1008 | + return numConditionalRequirements; |
| 1009 | + } |
| 1010 | + |
| 1011 | + BuiltinProtocolConformance(Type conformingType, ProtocolDecl *protocol, |
| 1012 | + GenericSignature genericSig, |
| 1013 | + ArrayRef<Requirement> conditionalRequirements); |
| 1014 | + |
| 1015 | +public: |
| 1016 | + /// Get the protocol being conformed to. |
| 1017 | + ProtocolDecl *getProtocol() const { |
| 1018 | + return protocol; |
| 1019 | + } |
| 1020 | + |
| 1021 | + /// Retrieve the generic signature that describes the type parameters used |
| 1022 | + /// within the conforming type. |
| 1023 | + GenericSignature getGenericSignature() const { |
| 1024 | + return genericSig; |
| 1025 | + } |
| 1026 | + |
| 1027 | + /// Get any requirements that must be satisfied for this conformance to apply. |
| 1028 | + Optional<ArrayRef<Requirement>> |
| 1029 | + getConditionalRequirementsIfAvailable() const { |
| 1030 | + return getConditionalRequirements(); |
| 1031 | + } |
| 1032 | + |
| 1033 | + /// Get any requirements that must be satisfied for this conformance to apply. |
| 1034 | + ArrayRef<Requirement> getConditionalRequirements() const { |
| 1035 | + return {getTrailingObjects<Requirement>(), numConditionalRequirements}; |
| 1036 | + } |
| 1037 | + |
| 1038 | + /// Get the declaration context that contains the nominal type declaration. |
| 1039 | + DeclContext *getDeclContext() const { |
| 1040 | + return getProtocol(); |
| 1041 | + } |
| 1042 | + |
| 1043 | + /// Retrieve the state of this conformance. |
| 1044 | + ProtocolConformanceState getState() const { |
| 1045 | + return ProtocolConformanceState::Complete; |
| 1046 | + } |
| 1047 | + |
| 1048 | + /// Get the kind of source from which this conformance comes. |
| 1049 | + ConformanceEntryKind getSourceKind() const { |
| 1050 | + return ConformanceEntryKind::Synthesized; |
| 1051 | + } |
| 1052 | + /// Get the protocol conformance which implied this implied conformance. |
| 1053 | + NormalProtocolConformance *getImplyingConformance() const { |
| 1054 | + return nullptr; |
| 1055 | + } |
| 1056 | + |
| 1057 | + bool hasTypeWitness(AssociatedTypeDecl *assocType) const { |
| 1058 | + llvm_unreachable("builtin-conformances never have associated types"); |
| 1059 | + } |
| 1060 | + |
| 1061 | + /// Retrieve the type witness and type decl (if one exists) |
| 1062 | + /// for the given associated type. |
| 1063 | + TypeWitnessAndDecl |
| 1064 | + getTypeWitnessAndDecl(AssociatedTypeDecl *assocType, |
| 1065 | + SubstOptions options=None) const { |
| 1066 | + llvm_unreachable("builtin-conformances never have associated types"); |
| 1067 | + } |
| 1068 | + |
| 1069 | + /// Given that the requirement signature of the protocol directly states |
| 1070 | + /// that the given dependent type must conform to the given protocol, |
| 1071 | + /// return its associated conformance. |
| 1072 | + ProtocolConformanceRef |
| 1073 | + getAssociatedConformance(Type assocType, ProtocolDecl *protocol) const { |
| 1074 | + llvm_unreachable("builtin-conformances never have associated types"); |
| 1075 | + } |
| 1076 | + |
| 1077 | + /// Retrieve the witness corresponding to the given value requirement. |
| 1078 | + ConcreteDeclRef getWitnessDeclRef(ValueDecl *requirement) const { |
| 1079 | + return ConcreteDeclRef(requirement); |
| 1080 | + } |
| 1081 | + |
| 1082 | + /// Determine whether the witness for the given requirement |
| 1083 | + /// is either the default definition or was otherwise deduced. |
| 1084 | + bool usesDefaultDefinition(AssociatedTypeDecl *requirement) const { |
| 1085 | + llvm_unreachable("builtin-conformances never have associated types"); |
| 1086 | + } |
| 1087 | + |
| 1088 | + static bool classof(const ProtocolConformance *conformance) { |
| 1089 | + return conformance->getKind() == ProtocolConformanceKind::Builtin; |
| 1090 | + } |
| 1091 | +}; |
| 1092 | + |
990 | 1093 | inline bool ProtocolConformance::isInvalid() const {
|
991 | 1094 | return getRootConformance()->isInvalid();
|
992 | 1095 | }
|
|
0 commit comments