Skip to content

Commit 730ecfe

Browse files
committed
[GSB] Start tracking the owning dependent type in requirement sources.
For a protocol requirement element within a requirement source, track both the protocol in which the requirement was introduced as well as the dependent type (relative to that protocol) on which the requirement was introduced. This information is important when reconstructing the path from a requirement-as-written to the location of a desired protocol conformance.
1 parent 84c5d3e commit 730ecfe

File tree

5 files changed

+143
-71
lines changed

5 files changed

+143
-71
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,15 @@ class GenericSignatureBuilder {
254254

255255
/// Add the requirements placed on the given type parameter
256256
/// to the given potential archetype.
257+
///
258+
/// \param dependentType A dependent type thar describes \c pa relative to
259+
/// its protocol, for protocol requirements.
260+
///
261+
/// FIXME: \c dependentType will be derivable from \c parentSource and \c pa
262+
/// when we're no longer putting conformance requirements directly on the
263+
/// representative.
257264
bool addInheritedRequirements(TypeDecl *decl, PotentialArchetype *pa,
265+
Type dependentType,
258266
const RequirementSource *parentSource,
259267
llvm::SmallPtrSetImpl<ProtocolDecl *> &visited);
260268

@@ -526,7 +534,9 @@ class GenericSignatureBuilder::RequirementSource final
526534

527535
/// The requirement is a protocol requirement.
528536
///
529-
/// This stores the protocol that introduced the requirement.
537+
/// This stores the protocol that introduced the requirement as well as the
538+
/// dependent type (relative to that protocol) to which the conformance
539+
/// appertains.
530540
ProtocolRequirement,
531541

532542
/// A requirement that was resolved via a superclass requirement.
@@ -554,7 +564,7 @@ class GenericSignatureBuilder::RequirementSource final
554564
/// The kind of storage we have.
555565
enum class StorageKind : uint8_t {
556566
RootArchetype,
557-
ProtocolDecl,
567+
StoredType,
558568
ProtocolConformance,
559569
AssociatedTypeDecl,
560570
};
@@ -570,8 +580,8 @@ class GenericSignatureBuilder::RequirementSource final
570580
/// The root archetype.
571581
PotentialArchetype *rootArchetype;
572582

573-
/// The protocol being described.
574-
ProtocolDecl *protocol;
583+
/// The type to which a requirement applies.
584+
TypeBase *type;
575585

576586
/// A protocol conformance used to satisfy the requirement.
577587
ProtocolConformance *conformance;
@@ -586,12 +596,12 @@ class GenericSignatureBuilder::RequirementSource final
586596
size_t numTrailingObjects(OverloadToken<ProtocolDecl *>) const {
587597
switch (kind) {
588598
case RequirementSignatureSelf:
599+
case ProtocolRequirement:
589600
return 1;
590601

591602
case Explicit:
592603
case Inferred:
593604
case NestedTypeNameMatch:
594-
case ProtocolRequirement:
595605
case Superclass:
596606
case Parent:
597607
case Concrete:
@@ -606,9 +616,11 @@ class GenericSignatureBuilder::RequirementSource final
606616
return hasTrailingWrittenRequirementLoc ? 1 : 0;
607617
}
608618

619+
#ifndef NDEBUG
609620
/// Determines whether we have been provided with an acceptable storage kind
610621
/// for the given requirement source kind.
611622
static bool isAcceptableStorageKind(Kind kind, StorageKind storageKind);
623+
#endif
612624

613625
/// Retrieve the opaque storage as a single pointer, for use in uniquing.
614626
const void *getOpaqueStorage1() const;
@@ -664,9 +676,9 @@ class GenericSignatureBuilder::RequirementSource final
664676
}
665677

666678
RequirementSource(Kind kind, const RequirementSource *parent,
667-
ProtocolDecl *protocol,
679+
Type type, ProtocolDecl *protocol,
668680
WrittenRequirementLoc writtenReqLoc)
669-
: kind(kind), storageKind(StorageKind::ProtocolDecl),
681+
: kind(kind), storageKind(StorageKind::StoredType),
670682
hasTrailingWrittenRequirementLoc(!writtenReqLoc.isNull()),
671683

672684
parent(parent) {
@@ -675,7 +687,9 @@ class GenericSignatureBuilder::RequirementSource final
675687
assert(isAcceptableStorageKind(kind, storageKind) &&
676688
"RequirementSource kind/storageKind mismatch");
677689

678-
storage.protocol = protocol;
690+
storage.type = type.getPointer();
691+
if (kind == ProtocolRequirement)
692+
getTrailingObjects<ProtocolDecl *>()[0] = protocol;
679693
if (hasTrailingWrittenRequirementLoc)
680694
getTrailingObjects<WrittenRequirementLoc>()[0] = writtenReqLoc;
681695
}
@@ -734,8 +748,9 @@ class GenericSignatureBuilder::RequirementSource final
734748
private:
735749
/// A requirement source that describes that a requirement comes from a
736750
/// requirement of the given protocol described by the parent.
737-
const RequirementSource *viaAbstractProtocolRequirement(
751+
const RequirementSource *viaProtocolRequirement(
738752
GenericSignatureBuilder &builder,
753+
Type dependentType,
739754
ProtocolDecl *protocol,
740755
WrittenRequirementLoc writtenLoc =
741756
WrittenRequirementLoc()) const;
@@ -880,7 +895,7 @@ class GenericSignatureBuilder::FloatingRequirementSource {
880895
struct {
881896
ProtocolDecl *protocol = nullptr;
882897
WrittenRequirementLoc written;
883-
} abstractProtocolReq;
898+
} protocolReq;
884899

885900
FloatingRequirementSource(Kind kind, Storage storage)
886901
: kind(kind), storage(storage) { }
@@ -907,27 +922,28 @@ class GenericSignatureBuilder::FloatingRequirementSource {
907922
return { Inferred, typeRepr };
908923
}
909924

910-
static FloatingRequirementSource viaAbstractProtocolRequirement(
925+
static FloatingRequirementSource viaProtocolRequirement(
911926
const RequirementSource *base,
912927
ProtocolDecl *inProtocol) {
913928
FloatingRequirementSource result{ AbstractProtocol, base };
914-
result.abstractProtocolReq.protocol = inProtocol;
929+
result.protocolReq.protocol = inProtocol;
915930
return result;
916931
}
917932

918-
static FloatingRequirementSource viaAbstractProtocolRequirement(
933+
static FloatingRequirementSource viaProtocolRequirement(
919934
const RequirementSource *base,
920935
ProtocolDecl *inProtocol,
921936
WrittenRequirementLoc written) {
922937
FloatingRequirementSource result{ AbstractProtocol, base };
923-
result.abstractProtocolReq.protocol = inProtocol;
924-
result.abstractProtocolReq.written = written;
938+
result.protocolReq.protocol = inProtocol;
939+
result.protocolReq.written = written;
925940
return result;
926941
}
927942

928943
/// Retrieve the complete requirement source rooted at the given potential
929944
/// archetype.
930-
const RequirementSource *getSource(PotentialArchetype *pa) const;
945+
const RequirementSource *getSource(PotentialArchetype *pa,
946+
Type dependentType) const;
931947

932948
/// Retrieve the source location for this requirement.
933949
SourceLoc getLoc() const;

0 commit comments

Comments
 (0)