@@ -74,6 +74,10 @@ class GenericSignatureBuilder {
74
74
using RequirementRHS =
75
75
llvm::PointerUnion3<Type, PotentialArchetype *, LayoutConstraint>;
76
76
77
+ // / The location of a requirement as written somewhere in the source.
78
+ typedef llvm::PointerUnion<const TypeRepr *, const RequirementRepr *>
79
+ WrittenRequirementLoc;
80
+
77
81
class RequirementSource ;
78
82
79
83
class FloatingRequirementSource ;
@@ -306,13 +310,19 @@ class GenericSignatureBuilder {
306
310
// / \brief Add a new generic parameter for which there may be requirements.
307
311
void addGenericParameter (GenericTypeParamType *GenericParam);
308
312
313
+ // / \brief Add a new requirement.
314
+ // /
315
+ // / \returns true if this requirement makes the set of requirements
316
+ // / inconsistent, in which case a diagnostic will have been issued.
317
+ bool addRequirement (const RequirementRepr *req);
318
+
309
319
// / \brief Add a new requirement.
310
320
// /
311
321
// / \returns true if this requirement makes the set of requirements
312
322
// / inconsistent, in which case a diagnostic will have been issued.
313
323
bool addRequirement (const RequirementRepr *Req,
314
- const RequirementSource * source = nullptr ,
315
- const SubstitutionMap *subMap = nullptr );
324
+ FloatingRequirementSource source,
325
+ const SubstitutionMap *subMap);
316
326
317
327
// / \brief Add an already-checked requirement.
318
328
// /
@@ -473,7 +483,10 @@ class GenericSignatureBuilder {
473
483
// / Requirement sources are uniqued within a generic signature builder.
474
484
class GenericSignatureBuilder ::RequirementSource final
475
485
: public llvm::FoldingSetNode,
476
- private llvm::TrailingObjects<RequirementSource, PotentialArchetype *> {
486
+ private llvm::TrailingObjects<RequirementSource, ProtocolDecl *,
487
+ WrittenRequirementLoc> {
488
+
489
+ friend class FloatingRequirementSource ;
477
490
478
491
public:
479
492
enum Kind : uint8_t {
@@ -541,8 +554,6 @@ class GenericSignatureBuilder::RequirementSource final
541
554
// / The kind of storage we have.
542
555
enum class StorageKind : uint8_t {
543
556
RootArchetype,
544
- TypeRepr,
545
- RequirementRepr,
546
557
ProtocolDecl,
547
558
ProtocolConformance,
548
559
AssociatedTypeDecl,
@@ -551,17 +562,14 @@ class GenericSignatureBuilder::RequirementSource final
551
562
// / The kind of storage we have.
552
563
const StorageKind storageKind;
553
564
565
+ // / Whether there is a trailing written requirement location.
566
+ const bool hasTrailingWrittenRequirementLoc;
567
+
554
568
// / The actual storage, described by \c storageKind.
555
569
union {
556
570
// / The root archetype.
557
571
PotentialArchetype *rootArchetype;
558
572
559
- // / The type representation describing where the requirement came from.
560
- const TypeRepr *typeRepr;
561
-
562
- // / Where a requirement came from.
563
- const RequirementRepr *requirementRepr;
564
-
565
573
// / The protocol being described.
566
574
ProtocolDecl *protocol;
567
575
@@ -574,16 +582,14 @@ class GenericSignatureBuilder::RequirementSource final
574
582
575
583
friend TrailingObjects;
576
584
577
- // / The trailing potential archetype, for
578
- size_t numTrailingObjects (OverloadToken<PotentialArchetype *>) const {
585
+ // / The trailing protocol declaration, if there is one.
586
+ size_t numTrailingObjects (OverloadToken<ProtocolDecl *>) const {
579
587
switch (kind) {
580
588
case RequirementSignatureSelf:
581
589
return 1 ;
582
590
583
591
case Explicit:
584
592
case Inferred:
585
- return storageKind == StorageKind::RootArchetype ? 0 : 1 ;
586
-
587
593
case NestedTypeNameMatch:
588
594
case ProtocolRequirement:
589
595
case Superclass:
@@ -595,16 +601,25 @@ class GenericSignatureBuilder::RequirementSource final
595
601
llvm_unreachable (" Unhandled RequirementSourceKind in switch." );
596
602
}
597
603
604
+ // / The trailing written requirement location, if there is one.
605
+ size_t numTrailingObjects (OverloadToken<WrittenRequirementLoc>) const {
606
+ return hasTrailingWrittenRequirementLoc ? 1 : 0 ;
607
+ }
608
+
598
609
// / Determines whether we have been provided with an acceptable storage kind
599
610
// / for the given requirement source kind.
600
611
static bool isAcceptableStorageKind (Kind kind, StorageKind storageKind);
601
612
602
613
// / Retrieve the opaque storage as a single pointer, for use in uniquing.
603
- const void *getOpaqueStorage () const ;
614
+ const void *getOpaqueStorage1 () const ;
615
+
616
+ // / Retrieve the second opaque storage as a single pointer, for use in
617
+ // / uniquing.
618
+ const void *getOpaqueStorage2 () const ;
604
619
605
- // / Retrieve the extra opaque storage as a single pointer, for use in
620
+ // / Retrieve the third opaque storage as a single pointer, for use in
606
621
// / uniquing.
607
- const void *getExtraOpaqueStorage () const ;
622
+ const void *getOpaqueStorage3 () const ;
608
623
609
624
// / Whether this kind of requirement source is a root.
610
625
static bool isRootKind (Kind kind) {
@@ -632,53 +647,43 @@ class GenericSignatureBuilder::RequirementSource final
632
647
// / requirement source with one of the "root" kinds.
633
648
const RequirementSource * const parent;
634
649
635
- RequirementSource (Kind kind, const RequirementSource *parent,
636
- PotentialArchetype *rootArchetype)
637
- : kind(kind), storageKind(StorageKind::RootArchetype), parent(parent) {
638
- assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
639
- " Root RequirementSource should not have parent (or vice versa)" );
650
+ RequirementSource (Kind kind, PotentialArchetype *rootArchetype,
651
+ ProtocolDecl *protocol,
652
+ WrittenRequirementLoc writtenReqLoc)
653
+ : kind(kind), storageKind(StorageKind::RootArchetype),
654
+ hasTrailingWrittenRequirementLoc (!writtenReqLoc.isNull()),
655
+ parent(nullptr ) {
640
656
assert (isAcceptableStorageKind (kind, storageKind) &&
641
657
" RequirementSource kind/storageKind mismatch" );
642
658
643
659
storage.rootArchetype = rootArchetype;
660
+ if (kind == RequirementSignatureSelf)
661
+ getTrailingObjects<ProtocolDecl *>()[0 ] = protocol;
662
+ if (hasTrailingWrittenRequirementLoc)
663
+ getTrailingObjects<WrittenRequirementLoc>()[0 ] = writtenReqLoc;
644
664
}
645
665
646
666
RequirementSource (Kind kind, const RequirementSource *parent,
647
- const TypeRepr *typeRepr)
648
- : kind(kind), storageKind(StorageKind::TypeRepr), parent(parent) {
649
- assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
650
- " Root RequirementSource should not have parent (or vice versa)" );
651
- assert (isAcceptableStorageKind (kind, storageKind) &&
652
- " RequirementSource kind/storageKind mismatch" );
667
+ ProtocolDecl *protocol,
668
+ WrittenRequirementLoc writtenReqLoc)
669
+ : kind(kind), storageKind(StorageKind::ProtocolDecl),
670
+ hasTrailingWrittenRequirementLoc(!writtenReqLoc.isNull()),
653
671
654
- storage.typeRepr = typeRepr;
655
- }
656
-
657
- RequirementSource (Kind kind, const RequirementSource *parent,
658
- const RequirementRepr *requirementRepr)
659
- : kind(kind), storageKind(StorageKind::RequirementRepr), parent(parent) {
660
- assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
661
- " Root RequirementSource should not have parent (or vice versa)" );
662
- assert (isAcceptableStorageKind (kind, storageKind) &&
663
- " RequirementSource kind/storageKind mismatch" );
664
-
665
- storage.requirementRepr = requirementRepr;
666
- }
667
-
668
- RequirementSource (Kind kind, const RequirementSource *parent,
669
- ProtocolDecl *protocol)
670
- : kind(kind), storageKind(StorageKind::ProtocolDecl), parent(parent) {
672
+ parent(parent) {
671
673
assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
672
674
" Root RequirementSource should not have parent (or vice versa)" );
673
675
assert (isAcceptableStorageKind (kind, storageKind) &&
674
676
" RequirementSource kind/storageKind mismatch" );
675
677
676
678
storage.protocol = protocol;
679
+ if (hasTrailingWrittenRequirementLoc)
680
+ getTrailingObjects<WrittenRequirementLoc>()[0 ] = writtenReqLoc;
677
681
}
678
682
679
683
RequirementSource (Kind kind, const RequirementSource *parent,
680
684
ProtocolConformance *conformance)
681
685
: kind(kind), storageKind(StorageKind::ProtocolConformance),
686
+ hasTrailingWrittenRequirementLoc(false ),
682
687
parent(parent) {
683
688
assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
684
689
" Root RequirementSource should not have parent (or vice versa)" );
@@ -691,6 +696,7 @@ class GenericSignatureBuilder::RequirementSource final
691
696
RequirementSource (Kind kind, const RequirementSource *parent,
692
697
AssociatedTypeDecl *assocType)
693
698
: kind(kind), storageKind(StorageKind::AssociatedTypeDecl),
699
+ hasTrailingWrittenRequirementLoc(false ),
694
700
parent(parent) {
695
701
assert ((static_cast <bool >(parent) != isRootKind (kind)) &&
696
702
" Root RequirementSource should not have parent (or vice versa)" );
@@ -705,15 +711,9 @@ class GenericSignatureBuilder::RequirementSource final
705
711
static const RequirementSource *forAbstract (PotentialArchetype *root);
706
712
707
713
// / Retrieve a requirement source representing an explicit requirement
708
- // / stated in an 'inheritance' clause.
714
+ // / stated in an 'inheritance' or 'where' clause.
709
715
static const RequirementSource *forExplicit (PotentialArchetype *root,
710
- const TypeRepr *typeRepr);
711
-
712
- // / Retrieve a requirement source representing an explicit requirement
713
- // / stated in an 'where' clause.
714
- static const RequirementSource *forExplicit (
715
- PotentialArchetype *root,
716
- const RequirementRepr *requirementRepr);
716
+ WrittenRequirementLoc writtenLoc);
717
717
718
718
// / Retrieve a requirement source representing a requirement that is
719
719
// / inferred from some part of a generic declaration's signature, e.g., the
@@ -731,12 +731,16 @@ class GenericSignatureBuilder::RequirementSource final
731
731
static const RequirementSource *forNestedTypeNameMatch (
732
732
PotentialArchetype *root);
733
733
734
+ private:
734
735
// / A requirement source that describes that a requirement comes from a
735
736
// / requirement of the given protocol described by the parent.
736
737
const RequirementSource *viaAbstractProtocolRequirement (
737
738
GenericSignatureBuilder &builder,
738
- ProtocolDecl *protocol) const ;
739
+ ProtocolDecl *protocol,
740
+ WrittenRequirementLoc writtenLoc =
741
+ WrittenRequirementLoc ()) const ;
739
742
743
+ public:
740
744
// / A requirement source that describes that a requirement that is resolved
741
745
// / via a superclass requirement.
742
746
const RequirementSource *viaSuperclass (
@@ -789,15 +793,17 @@ class GenericSignatureBuilder::RequirementSource final
789
793
790
794
// / Retrieve the type representation for this requirement, if there is one.
791
795
const TypeRepr *getTypeRepr () const {
792
- if (storageKind != StorageKind::TypeRepr) return nullptr ;
793
- return storage.typeRepr ;
796
+ if (!hasTrailingWrittenRequirementLoc) return nullptr ;
797
+ return getTrailingObjects<WrittenRequirementLoc>()[0 ]
798
+ .dyn_cast <const TypeRepr *>();
794
799
}
795
800
796
801
// / Retrieve the requirement representation for this requirement, if there is
797
802
// / one.
798
803
const RequirementRepr *getRequirementRepr () const {
799
- if (storageKind != StorageKind::RequirementRepr) return nullptr ;
800
- return storage.requirementRepr ;
804
+ if (!hasTrailingWrittenRequirementLoc) return nullptr ;
805
+ return getTrailingObjects<WrittenRequirementLoc>()[0 ]
806
+ .dyn_cast <const RequirementRepr *>();
801
807
}
802
808
803
809
// / Retrieve the protocol for this requirement, if there is one.
@@ -818,17 +824,19 @@ class GenericSignatureBuilder::RequirementSource final
818
824
819
825
// / Profiling support for \c FoldingSet.
820
826
void Profile (llvm::FoldingSetNodeID &ID) {
821
- Profile (ID, kind, parent, getOpaqueStorage (), getExtraOpaqueStorage ());
827
+ Profile (ID, kind, parent, getOpaqueStorage1 (), getOpaqueStorage2 (),
828
+ getOpaqueStorage3 ());
822
829
}
823
830
824
831
// / Profiling support for \c FoldingSet.
825
832
static void Profile (llvm::FoldingSetNodeID &ID, Kind kind,
826
- const RequirementSource *parent, const void *storage ,
827
- const void *extraStorage ) {
833
+ const RequirementSource *parent, const void *storage1 ,
834
+ const void *storage2, const void *storage3 ) {
828
835
ID.AddInteger (kind);
829
836
ID.AddPointer (parent);
830
- ID.AddPointer (storage);
831
- ID.AddPointer (extraStorage);
837
+ ID.AddPointer (storage1);
838
+ ID.AddPointer (storage2);
839
+ ID.AddPointer (storage3);
832
840
}
833
841
834
842
LLVM_ATTRIBUTE_DEPRECATED (
@@ -857,7 +865,9 @@ class GenericSignatureBuilder::FloatingRequirementSource {
857
865
// / An explicit requirement source lacking a root.
858
866
Explicit,
859
867
// / An inferred requirement source lacking a root.
860
- Inferred
868
+ Inferred,
869
+ // / A requirement source augmented by an abstract protocol requirement
870
+ AbstractProtocol,
861
871
} kind;
862
872
863
873
using Storage =
@@ -866,6 +876,12 @@ class GenericSignatureBuilder::FloatingRequirementSource {
866
876
867
877
Storage storage;
868
878
879
+ // Additional storage for an abstract protocol requirement.
880
+ struct {
881
+ ProtocolDecl *protocol = nullptr ;
882
+ WrittenRequirementLoc written;
883
+ } abstractProtocolReq;
884
+
869
885
FloatingRequirementSource (Kind kind, Storage storage)
870
886
: kind(kind), storage(storage) { }
871
887
@@ -891,6 +907,24 @@ class GenericSignatureBuilder::FloatingRequirementSource {
891
907
return { Inferred, typeRepr };
892
908
}
893
909
910
+ static FloatingRequirementSource viaAbstractProtocolRequirement (
911
+ const RequirementSource *base,
912
+ ProtocolDecl *inProtocol) {
913
+ FloatingRequirementSource result{ AbstractProtocol, base };
914
+ result.abstractProtocolReq .protocol = inProtocol;
915
+ return result;
916
+ }
917
+
918
+ static FloatingRequirementSource viaAbstractProtocolRequirement (
919
+ const RequirementSource *base,
920
+ ProtocolDecl *inProtocol,
921
+ WrittenRequirementLoc written) {
922
+ FloatingRequirementSource result{ AbstractProtocol, base };
923
+ result.abstractProtocolReq .protocol = inProtocol;
924
+ result.abstractProtocolReq .written = written;
925
+ return result;
926
+ }
927
+
894
928
// / Retrieve the complete requirement source rooted at the given potential
895
929
// / archetype.
896
930
const RequirementSource *getSource (PotentialArchetype *pa) const ;
0 commit comments