Skip to content

[AST] Progress toward handling indirect conformances in witness tables #7943

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions include/swift/AST/GenericSignatureBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,15 @@ class GenericSignatureBuilder {

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

Expand Down Expand Up @@ -526,7 +534,9 @@ class GenericSignatureBuilder::RequirementSource final

/// The requirement is a protocol requirement.
///
/// This stores the protocol that introduced the requirement.
/// This stores the protocol that introduced the requirement as well as the
/// dependent type (relative to that protocol) to which the conformance
/// appertains.
ProtocolRequirement,

/// A requirement that was resolved via a superclass requirement.
Expand Down Expand Up @@ -554,7 +564,7 @@ class GenericSignatureBuilder::RequirementSource final
/// The kind of storage we have.
enum class StorageKind : uint8_t {
RootArchetype,
ProtocolDecl,
StoredType,
ProtocolConformance,
AssociatedTypeDecl,
};
Expand All @@ -570,8 +580,8 @@ class GenericSignatureBuilder::RequirementSource final
/// The root archetype.
PotentialArchetype *rootArchetype;

/// The protocol being described.
ProtocolDecl *protocol;
/// The type to which a requirement applies.
TypeBase *type;

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

case Explicit:
case Inferred:
case NestedTypeNameMatch:
case ProtocolRequirement:
case Superclass:
case Parent:
case Concrete:
Expand All @@ -606,9 +616,11 @@ class GenericSignatureBuilder::RequirementSource final
return hasTrailingWrittenRequirementLoc ? 1 : 0;
}

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

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

RequirementSource(Kind kind, const RequirementSource *parent,
ProtocolDecl *protocol,
Type type, ProtocolDecl *protocol,
WrittenRequirementLoc writtenReqLoc)
: kind(kind), storageKind(StorageKind::ProtocolDecl),
: kind(kind), storageKind(StorageKind::StoredType),
hasTrailingWrittenRequirementLoc(!writtenReqLoc.isNull()),

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

storage.protocol = protocol;
storage.type = type.getPointer();
if (kind == ProtocolRequirement)
getTrailingObjects<ProtocolDecl *>()[0] = protocol;
if (hasTrailingWrittenRequirementLoc)
getTrailingObjects<WrittenRequirementLoc>()[0] = writtenReqLoc;
}
Expand Down Expand Up @@ -734,8 +748,9 @@ class GenericSignatureBuilder::RequirementSource final
private:
/// A requirement source that describes that a requirement comes from a
/// requirement of the given protocol described by the parent.
const RequirementSource *viaAbstractProtocolRequirement(
const RequirementSource *viaProtocolRequirement(
GenericSignatureBuilder &builder,
Type dependentType,
ProtocolDecl *protocol,
WrittenRequirementLoc writtenLoc =
WrittenRequirementLoc()) const;
Expand Down Expand Up @@ -880,7 +895,7 @@ class GenericSignatureBuilder::FloatingRequirementSource {
struct {
ProtocolDecl *protocol = nullptr;
WrittenRequirementLoc written;
} abstractProtocolReq;
} protocolReq;

FloatingRequirementSource(Kind kind, Storage storage)
: kind(kind), storage(storage) { }
Expand All @@ -907,27 +922,28 @@ class GenericSignatureBuilder::FloatingRequirementSource {
return { Inferred, typeRepr };
}

static FloatingRequirementSource viaAbstractProtocolRequirement(
static FloatingRequirementSource viaProtocolRequirement(
const RequirementSource *base,
ProtocolDecl *inProtocol) {
FloatingRequirementSource result{ AbstractProtocol, base };
result.abstractProtocolReq.protocol = inProtocol;
result.protocolReq.protocol = inProtocol;
return result;
}

static FloatingRequirementSource viaAbstractProtocolRequirement(
static FloatingRequirementSource viaProtocolRequirement(
const RequirementSource *base,
ProtocolDecl *inProtocol,
WrittenRequirementLoc written) {
FloatingRequirementSource result{ AbstractProtocol, base };
result.abstractProtocolReq.protocol = inProtocol;
result.abstractProtocolReq.written = written;
result.protocolReq.protocol = inProtocol;
result.protocolReq.written = written;
return result;
}

/// Retrieve the complete requirement source rooted at the given potential
/// archetype.
const RequirementSource *getSource(PotentialArchetype *pa) const;
const RequirementSource *getSource(PotentialArchetype *pa,
Type dependentType) const;

/// Retrieve the source location for this requirement.
SourceLoc getLoc() const;
Expand Down
Loading