@@ -35,6 +35,7 @@ class ASTContext;
35
35
class DiagnosticEngine ;
36
36
class GenericParamList ;
37
37
class NormalProtocolConformance ;
38
+ class RootProtocolConformance ;
38
39
class ProtocolConformance ;
39
40
class ModuleDecl ;
40
41
class SubstitutableType ;
@@ -58,6 +59,8 @@ enum class ProtocolConformanceKind {
58
59
// / "Normal" conformance of a (possibly generic) nominal type, which
59
60
// / contains complete mappings.
60
61
Normal,
62
+ // / Self-conformance of a protocol to itself.
63
+ Self,
61
64
// / Conformance for a specialization of a generic type, which projects the
62
65
// / underlying generic conformance.
63
66
Specialized,
@@ -259,6 +262,7 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
259
262
SubstitutionMap getSubstitutions (ModuleDecl *M) const ;
260
263
261
264
// / Get the underlying normal conformance.
265
+ // / FIXME: remove uses of this.
262
266
const NormalProtocolConformance *getRootNormalConformance () const ;
263
267
264
268
// / Get the underlying normal conformance.
@@ -268,6 +272,15 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
268
272
->getRootNormalConformance ());
269
273
}
270
274
275
+ // / Get the underlying root conformance.
276
+ const RootProtocolConformance *getRootConformance () const ;
277
+
278
+ // / Get the underlying root conformance.
279
+ RootProtocolConformance *getRootConformance () {
280
+ return const_cast <RootProtocolConformance *>(
281
+ const_cast <const ProtocolConformance *>(this )->getRootConformance ());
282
+ }
283
+
271
284
// / Determine whether this protocol conformance is visible from the
272
285
// / given declaration context.
273
286
bool isVisibleFrom (const DeclContext *dc) const ;
@@ -322,6 +335,41 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
322
335
void dump (llvm::raw_ostream &out, unsigned indent = 0 ) const ;
323
336
};
324
337
338
+ // / A "root" protocol conformance states some sort of ground truth
339
+ // / about the conforming type and the required protocol. Either:
340
+ // /
341
+ // / - the type is directly declared to conform to the protocol (a
342
+ // / normal conformance) or
343
+ // / - the protocol's existential type is known to conform to itself (a
344
+ // / self-conformance).
345
+ class RootProtocolConformance : public ProtocolConformance {
346
+ protected:
347
+ RootProtocolConformance (ProtocolConformanceKind kind, Type conformingType)
348
+ : ProtocolConformance(kind, conformingType) {}
349
+
350
+ public:
351
+ // / Retrieve the location of this conformance.
352
+ SourceLoc getLoc () const ;
353
+
354
+ // / Is this a behavior conformance?
355
+ bool isBehaviorConformance () const ;
356
+
357
+ bool isInvalid () const ;
358
+
359
+ bool hasWitness (ValueDecl *requirement) const ;
360
+ Witness getWitness (ValueDecl *requirement, LazyResolver *resolver) const ;
361
+
362
+ // / Retrieve the witness corresponding to the given value requirement.
363
+ // / TODO: maybe this should return a Witness?
364
+ ConcreteDeclRef getWitnessDeclRef (ValueDecl *requirement,
365
+ LazyResolver *resolver) const ;
366
+
367
+ static bool classof (const ProtocolConformance *conformance) {
368
+ return conformance->getKind () == ProtocolConformanceKind::Normal ||
369
+ conformance->getKind () == ProtocolConformanceKind::Self;
370
+ }
371
+ };
372
+
325
373
// / Normal protocol conformance, which involves mapping each of the protocol
326
374
// / requirements to a witness.
327
375
// /
@@ -337,7 +385,7 @@ class alignas(1 << DeclAlignInBits) ProtocolConformance {
337
385
// / Here, there is a normal protocol conformance for both \c A and \c B<T>,
338
386
// / providing the witnesses \c A.foo and \c B<T>.foo, respectively, for the
339
387
// / requirement \c foo.
340
- class NormalProtocolConformance : public ProtocolConformance ,
388
+ class NormalProtocolConformance : public RootProtocolConformance ,
341
389
public llvm::FoldingSetNode
342
390
{
343
391
// / \brief The protocol being conformed to and its current state.
@@ -406,7 +454,7 @@ class NormalProtocolConformance : public ProtocolConformance,
406
454
NormalProtocolConformance (Type conformingType, ProtocolDecl *protocol,
407
455
SourceLoc loc, DeclContext *dc,
408
456
ProtocolConformanceState state)
409
- : ProtocolConformance (ProtocolConformanceKind::Normal, conformingType),
457
+ : RootProtocolConformance (ProtocolConformanceKind::Normal, conformingType),
410
458
ProtocolAndState (protocol, state), Loc(loc), ContextAndInvalid(dc, false )
411
459
{
412
460
assert (!conformingType->hasArchetype () &&
@@ -417,7 +465,7 @@ class NormalProtocolConformance : public ProtocolConformance,
417
465
ProtocolDecl *protocol,
418
466
SourceLoc loc, AbstractStorageDecl *behaviorStorage,
419
467
ProtocolConformanceState state)
420
- : ProtocolConformance (ProtocolConformanceKind::Normal, conformingType),
468
+ : RootProtocolConformance (ProtocolConformanceKind::Normal, conformingType),
421
469
ProtocolAndState(protocol, state), Loc(loc),
422
470
ContextAndInvalid(behaviorStorage, false )
423
471
{
@@ -579,8 +627,6 @@ class NormalProtocolConformance : public ProtocolConformance,
579
627
580
628
// / Retrieve the value witness corresponding to the given requirement.
581
629
Witness getWitness (ValueDecl *requirement, LazyResolver *resolver) const ;
582
- ConcreteDeclRef getWitnessDeclRef (ValueDecl *requirement,
583
- LazyResolver *resolver) const ;
584
630
585
631
// / Determine whether the protocol conformance has a witness for the given
586
632
// / requirement.
@@ -670,6 +716,104 @@ class NormalProtocolConformance : public ProtocolConformance,
670
716
}
671
717
};
672
718
719
+ // / The conformance of a protocol to itself.
720
+ // /
721
+ // / For now, we generally do not use this type in ProtocolConformanceRefs;
722
+ // / it's only used to anchor structures relating to emitting witness tables
723
+ // / for self-conformances.
724
+ class SelfProtocolConformance : public RootProtocolConformance {
725
+ friend class ASTContext ;
726
+
727
+ SelfProtocolConformance (Type conformingType)
728
+ : RootProtocolConformance(ProtocolConformanceKind::Self, conformingType) {
729
+ }
730
+
731
+ public:
732
+ // / Get the protocol being conformed to.
733
+ ProtocolDecl *getProtocol () const {
734
+ return getType ()->castTo <ProtocolType>()->getDecl ();
735
+ }
736
+
737
+ // / Get the declaration context in which this conformance was declared.
738
+ DeclContext *getDeclContext () const {
739
+ return getProtocol ();
740
+ }
741
+
742
+ // / Retrieve the location of this conformance.
743
+ SourceLoc getLoc () const {
744
+ return getProtocol ()->getLoc ();
745
+ }
746
+
747
+ ProtocolConformanceState getState () const {
748
+ return ProtocolConformanceState::Complete;
749
+ }
750
+
751
+ bool isInvalid () const {
752
+ return false ;
753
+ }
754
+
755
+ ConformanceEntryKind getSourceKind () const {
756
+ return ConformanceEntryKind::Explicit; // FIXME?
757
+ }
758
+
759
+ NormalProtocolConformance *getImplyingConformance () const {
760
+ llvm_unreachable (" never an implied conformance" );
761
+ }
762
+
763
+ bool hasTypeWitness (AssociatedTypeDecl *assocType,
764
+ LazyResolver *resolver) const {
765
+ llvm_unreachable (" self-conformances never have associated types" );
766
+ }
767
+
768
+ std::pair<Type, TypeDecl *>
769
+ getTypeWitnessAndDecl (AssociatedTypeDecl *assocType,
770
+ LazyResolver *resolver,
771
+ SubstOptions options) const {
772
+ llvm_unreachable (" self-conformances never have associated types" );
773
+ }
774
+
775
+ Type getTypeWitness (AssociatedTypeDecl *assocType,
776
+ LazyResolver *resolver,
777
+ SubstOptions options) const {
778
+ llvm_unreachable (" self-conformances never have associated types" );
779
+ }
780
+
781
+ bool usesDefaultDefinition (AssociatedTypeDecl *requirement) const {
782
+ llvm_unreachable (" self-conformances never have associated types" );
783
+ }
784
+
785
+ ProtocolConformanceRef getAssociatedConformance (Type assocType,
786
+ ProtocolDecl *protocol,
787
+ LazyResolver *resolver) const {
788
+ llvm_unreachable (" self-conformances never have associated types" );
789
+ }
790
+
791
+ bool hasWitness (ValueDecl *requirement) const {
792
+ return true ;
793
+ }
794
+ Witness getWitness (ValueDecl *requirement, LazyResolver *resolver) const ;
795
+
796
+ Optional<ArrayRef<Requirement>> getConditionalRequirementsIfAvailable () const {
797
+ return ArrayRef<Requirement>();
798
+ }
799
+
800
+ // / Get any additional requirements that are required for this conformance to
801
+ // / be satisfied.
802
+ ArrayRef<Requirement> getConditionalRequirements () const {
803
+ return ArrayRef<Requirement>();
804
+ }
805
+
806
+ static bool classof (const ProtocolConformance *conformance) {
807
+ return conformance->getKind () == ProtocolConformanceKind::Self;
808
+ }
809
+ };
810
+
811
+ inline bool RootProtocolConformance::isBehaviorConformance () const {
812
+ if (auto normal = dyn_cast<NormalProtocolConformance>(this ))
813
+ return normal->isBehaviorConformance ();
814
+ return false ;
815
+ }
816
+
673
817
// / Specialized protocol conformance, which projects a generic protocol
674
818
// / conformance to one of the specializations of the generic type.
675
819
// /
@@ -934,11 +1078,11 @@ class InheritedProtocolConformance : public ProtocolConformance,
934
1078
};
935
1079
936
1080
inline bool ProtocolConformance::isInvalid () const {
937
- return getRootNormalConformance ()->isInvalid ();
1081
+ return getRootConformance ()->isInvalid ();
938
1082
}
939
1083
940
1084
inline bool ProtocolConformance::hasWitness (ValueDecl *requirement) const {
941
- return getRootNormalConformance ()->hasWitness (requirement);
1085
+ return getRootConformance ()->hasWitness (requirement);
942
1086
}
943
1087
944
1088
} // end namespace swift
0 commit comments