Skip to content

Commit a1c03db

Browse files
committed
AST: Generalize ProtocolDecl::getRequirementSignature() to a new RequirementSignature type
The RequirementSignature generalizes the old ArrayRef<Requirement> which stores the minimal requirements that a conforming type's witnesses must satisfy, to also record the protocol typealiases defined in the protocol.
1 parent c58d9d8 commit a1c03db

31 files changed

+181
-122
lines changed

include/swift/AST/Decl.h

+9-19
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "swift/AST/IfConfigClause.h"
3030
#include "swift/AST/LayoutConstraint.h"
3131
#include "swift/AST/ReferenceCounting.h"
32+
#include "swift/AST/RequirementSignature.h"
3233
#include "swift/AST/StorageImpl.h"
3334
#include "swift/AST/TypeAlignments.h"
3435
#include "swift/AST/TypeWalker.h"
@@ -525,7 +526,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
525526
IsComputingSemanticMembers : 1
526527
);
527528

528-
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+1+1+1+1+8+16,
529+
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+1+1+1+1+8,
529530
/// Whether the \c RequiresClass bit is valid.
530531
RequiresClassValid : 1,
531532

@@ -564,10 +565,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
564565

565566
/// If this is a compiler-known protocol, this will be a KnownProtocolKind
566567
/// value, plus one. Otherwise, it will be 0.
567-
KnownProtocol : 8, // '8' for speed. This only needs 6.
568-
569-
/// The number of requirements in the requirement signature.
570-
NumRequirementsInSignature : 16
568+
KnownProtocol : 8 // '8' for speed. This only needs 6.
571569
);
572570

573571
SWIFT_INLINE_BITFIELD(ClassDecl, NominalTypeDecl, 1+1+2+1+1+1+1+1+1,
@@ -4313,7 +4311,7 @@ class ProtocolDecl final : public NominalTypeDecl {
43134311

43144312
/// The generic signature representing exactly the new requirements introduced
43154313
/// by this protocol.
4316-
const Requirement *RequirementSignature = nullptr;
4314+
Optional<RequirementSignature> RequirementSig;
43174315

43184316
/// Returns the cached result of \c requiresClass or \c None if it hasn't yet
43194317
/// been computed.
@@ -4574,34 +4572,26 @@ class ProtocolDecl final : public NominalTypeDecl {
45744572
/// requirements. Computed from the structural requirements, above.
45754573
ArrayRef<ProtocolDecl *> getProtocolDependencies() const;
45764574

4577-
/// Retrieve the requirements that describe this protocol.
4578-
///
4579-
/// These are the requirements including any inherited protocols
4580-
/// and conformances for associated types that are introduced in this
4581-
/// protocol. Requirements implied via any other protocol (e.g., inherited
4582-
/// protocols of the inherited protocols) are not mentioned. The conformance
4583-
/// requirements listed here become entries in the witness table.
4584-
ArrayRef<Requirement> getRequirementSignature() const;
4575+
/// Retrieve the requirements that describe this protocol from the point of
4576+
/// view of the generic system; see RequirementSignature.h for details.
4577+
RequirementSignature getRequirementSignature() const;
45854578

45864579
/// Is the requirement signature currently being computed?
45874580
bool isComputingRequirementSignature() const;
45884581

45894582
/// Has the requirement signature been computed yet?
45904583
bool isRequirementSignatureComputed() const {
4591-
return RequirementSignature != nullptr;
4584+
return RequirementSig.hasValue();
45924585
}
45934586

4594-
void setRequirementSignature(ArrayRef<Requirement> requirements);
4587+
void setRequirementSignature(RequirementSignature requirementSig);
45954588

45964589
void setLazyRequirementSignature(LazyMemberLoader *lazyLoader,
45974590
uint64_t requirementSignatureData);
45984591

45994592
void setLazyAssociatedTypeMembers(LazyMemberLoader *lazyLoader,
46004593
uint64_t associatedTypesData);
46014594

4602-
private:
4603-
ArrayRef<Requirement> getCachedRequirementSignature() const;
4604-
46054595
public:
46064596
// Implement isa/cast/dyncast/etc.
46074597
static bool classof(const Decl *D) {
+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//===--- RequirementSignature.h - Requirement Signature AST -----*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the RequirementSignature class.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef SWIFT_AST_REQUIREMENT_SIGNATURE_H
18+
#define SWIFT_AST_REQUIREMENT_SIGNATURE_H
19+
20+
#include "swift/AST/Type.h"
21+
22+
namespace swift {
23+
24+
/// A description of a typealias defined in a protocol.
25+
class ProtocolTypeAlias final {
26+
Identifier Name;
27+
Type UnderlyingType;
28+
29+
public:
30+
ProtocolTypeAlias(Identifier name, Type underlyingType)
31+
: Name(name), UnderlyingType(underlyingType) {}
32+
33+
/// Returns the name of the typealias.
34+
Identifier getName() const { return Name; }
35+
36+
/// Returns the underlying type of the typealias.
37+
Type getUnderlyingType() const { return UnderlyingType; }
38+
};
39+
40+
/// The requirements that describe a protocol from the viewpoint of the
41+
/// generics system.
42+
class RequirementSignature final {
43+
ArrayRef<Requirement> Requirements;
44+
ArrayRef<ProtocolTypeAlias> TypeAliases;
45+
46+
public:
47+
RequirementSignature() = default;
48+
49+
RequirementSignature(ArrayRef<Requirement> requirements,
50+
ArrayRef<ProtocolTypeAlias> typeAliases)
51+
: Requirements(requirements), TypeAliases(typeAliases) {}
52+
53+
/// The requirements including any inherited protocols and conformances for
54+
/// associated types that are introduced in this protocol.
55+
///
56+
/// Requirements implied via any other protocol (e.g., inherited protocols
57+
/// of the inherited protocols) are not mentioned.
58+
///
59+
/// The conformance requirements listed here become entries in witness tables
60+
/// for conformances to this protocol.
61+
ArrayRef<Requirement> getRequirements() const {
62+
return Requirements;
63+
}
64+
65+
ArrayRef<ProtocolTypeAlias> getTypeAliases() const {
66+
return TypeAliases;
67+
}
68+
};
69+
70+
} // end namespace swift
71+
72+
#endif // SWIFT_AST_REQUIREMENT_SIGNATURE_H

include/swift/AST/TypeCheckRequests.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ class ProtocolDependenciesRequest :
476476
/// be folded into RequirementSignatureRequest.
477477
class RequirementSignatureRequestRQM :
478478
public SimpleRequest<RequirementSignatureRequestRQM,
479-
ArrayRef<Requirement>(ProtocolDecl *),
479+
RequirementSignature(ProtocolDecl *),
480480
RequestFlags::Cached> {
481481
public:
482482
using SimpleRequest::SimpleRequest;
@@ -485,7 +485,7 @@ class RequirementSignatureRequestRQM :
485485
friend SimpleRequest;
486486

487487
// Evaluation.
488-
ArrayRef<Requirement>
488+
RequirementSignature
489489
evaluate(Evaluator &evaluator, ProtocolDecl *proto) const;
490490

491491
public:
@@ -495,7 +495,7 @@ class RequirementSignatureRequestRQM :
495495
/// Compute the requirements that describe a protocol.
496496
class RequirementSignatureRequest :
497497
public SimpleRequest<RequirementSignatureRequest,
498-
ArrayRef<Requirement>(ProtocolDecl *),
498+
RequirementSignature(ProtocolDecl *),
499499
RequestFlags::SeparatelyCached> {
500500
public:
501501
using SimpleRequest::SimpleRequest;
@@ -504,14 +504,14 @@ class RequirementSignatureRequest :
504504
friend SimpleRequest;
505505

506506
// Evaluation.
507-
ArrayRef<Requirement>
507+
RequirementSignature
508508
evaluate(Evaluator &evaluator, ProtocolDecl *proto) const;
509509

510510
public:
511511
// Separate caching.
512512
bool isCached() const { return true; }
513-
Optional<ArrayRef<Requirement>> getCachedResult() const;
514-
void cacheResult(ArrayRef<Requirement> value) const;
513+
Optional<RequirementSignature> getCachedResult() const;
514+
void cacheResult(RequirementSignature value) const;
515515
};
516516

517517
/// Compute the default definition type of an associated type.

include/swift/AST/TypeCheckerTypeIDZone.def

+2-2
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,10 @@ SWIFT_REQUEST(TypeChecker, ProtocolDependenciesRequest,
258258
ArrayRef<ProtocolDecl *>(ProtocolDecl *), Cached,
259259
HasNearestLocation)
260260
SWIFT_REQUEST(TypeChecker, RequirementSignatureRequestRQM,
261-
ArrayRef<Requirement>(ProtocolDecl *), Cached,
261+
RequirementSignature(ProtocolDecl *), Cached,
262262
NoLocationInfo)
263263
SWIFT_REQUEST(TypeChecker, RequirementSignatureRequest,
264-
ArrayRef<Requirement>(ProtocolDecl *), SeparatelyCached,
264+
RequirementSignature(ProtocolDecl *), SeparatelyCached,
265265
NoLocationInfo)
266266
SWIFT_REQUEST(TypeChecker, RequiresOpaqueAccessorsRequest, bool(VarDecl *),
267267
SeparatelyCached, NoLocationInfo)

include/swift/IRGen/Linking.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/AST/Module.h"
1818
#include "swift/AST/ProtocolAssociations.h"
1919
#include "swift/AST/ProtocolConformance.h"
20+
#include "swift/AST/RequirementSignature.h"
2021
#include "swift/AST/Types.h"
2122
#include "swift/IRGen/ValueWitness.h"
2223
#include "swift/SIL/SILFunction.h"
@@ -607,7 +608,7 @@ class LinkEntity {
607608
CanType associatedType,
608609
ProtocolDecl *requirement) {
609610
unsigned index = 0;
610-
for (const auto &reqt : proto->getRequirementSignature()) {
611+
for (const auto &reqt : proto->getRequirementSignature().getRequirements()) {
611612
if (reqt.getKind() == RequirementKind::Conformance &&
612613
reqt.getFirstType()->getCanonicalType() == associatedType &&
613614
reqt.getProtocolDecl() == requirement) {
@@ -631,7 +632,7 @@ class LinkEntity {
631632
static std::pair<CanType, ProtocolDecl*>
632633
getAssociatedConformanceByIndex(const ProtocolDecl *proto,
633634
unsigned index) {
634-
auto &reqt = proto->getRequirementSignature()[index];
635+
auto &reqt = proto->getRequirementSignature().getRequirements()[index];
635636
assert(reqt.getKind() == RequirementKind::Conformance);
636637
return { reqt.getFirstType()->getCanonicalType(),
637638
reqt.getProtocolDecl() };

include/swift/SIL/SILWitnessVisitor.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ template <class T> class SILWitnessVisitor : public ASTVisitor<T> {
5353
// The protocol conformance descriptor gets added first.
5454
asDerived().addProtocolConformanceDescriptor();
5555

56-
for (const auto &reqt : protocol->getRequirementSignature()) {
56+
auto requirements = protocol->getRequirementSignature().getRequirements();
57+
for (const auto &reqt : requirements) {
5758
switch (reqt.getKind()) {
5859
// These requirements don't show up in the witness table.
5960
case RequirementKind::Superclass:

lib/APIDigester/ModuleAnalyzerNodes.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1194,7 +1194,8 @@ static StringRef printGenericSignature(SDKContext &Ctx, Decl *D, bool Canonical)
11941194
llvm::SmallString<32> Result;
11951195
llvm::raw_svector_ostream OS(Result);
11961196
if (auto *PD = dyn_cast<ProtocolDecl>(D)) {
1197-
return printGenericSignature(Ctx, PD->getRequirementSignature(), Canonical);
1197+
return printGenericSignature(Ctx, PD->getRequirementSignature().getRequirements(),
1198+
Canonical);
11981199
}
11991200
PrintOptions Opts = getTypePrintOpts(Ctx.getOpts());
12001201
if (auto *GC = D->getAsGenericContext()) {

lib/AST/ASTDumper.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -618,8 +618,8 @@ namespace {
618618

619619
OS << " requirement signature=";
620620
if (PD->isRequirementSignatureComputed()) {
621-
OS << GenericSignature::get({PD->getProtocolSelfType()} ,
622-
PD->getRequirementSignature())
621+
auto requirements = PD->getRequirementSignature().getRequirements();
622+
OS << GenericSignature::get({PD->getProtocolSelfType()}, requirements)
623623
->getAsString();
624624
} else {
625625
OS << "<null>";

lib/AST/ASTMangler.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -3284,9 +3284,8 @@ void ASTMangler::appendDependentProtocolConformance(
32843284

32853285
// Conformances are relative to the current protocol's requirement
32863286
// signature.
3287-
auto index =
3288-
conformanceRequirementIndex(entry,
3289-
currentProtocol->getRequirementSignature());
3287+
auto reqs = currentProtocol->getRequirementSignature().getRequirements();
3288+
auto index = conformanceRequirementIndex(entry, reqs);
32903289

32913290
// Inherited conformance.
32923291
bool isInheritedConformance =

lib/AST/ASTPrinter.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1487,7 +1487,7 @@ void PrintAST::printInheritedFromRequirementSignature(ProtocolDecl *proto,
14871487
Decl *attachingTo) {
14881488
printGenericSignature(
14891489
GenericSignature::get({proto->getProtocolSelfType()} ,
1490-
proto->getRequirementSignature()),
1490+
proto->getRequirementSignature().getRequirements()),
14911491
PrintInherited,
14921492
[&](const Requirement &req) {
14931493
// Skip the inferred 'Self : AnyObject' constraint if this is an
@@ -1511,7 +1511,7 @@ void PrintAST::printWhereClauseFromRequirementSignature(ProtocolDecl *proto,
15111511
flags |= SwapSelfAndDependentMemberType;
15121512
printGenericSignature(
15131513
GenericSignature::get({proto->getProtocolSelfType()} ,
1514-
proto->getRequirementSignature()),
1514+
proto->getRequirementSignature().getRequirements()),
15151515
flags,
15161516
[&](const Requirement &req) {
15171517
auto location = bestRequirementPrintLocation(proto, req);

lib/AST/ASTVerifier.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -2720,7 +2720,8 @@ class Verifier : public ASTWalker {
27202720
if (!normal->isInvalid()){
27212721
auto conformances = normal->getSignatureConformances();
27222722
unsigned idx = 0;
2723-
for (const auto &req : proto->getRequirementSignature()) {
2723+
auto reqs = proto->getRequirementSignature().getRequirements();
2724+
for (const auto &req : reqs) {
27242725
if (req.getKind() != RequirementKind::Conformance)
27252726
continue;
27262727

lib/AST/Decl.cpp

+6-20
Original file line numberDiff line numberDiff line change
@@ -5222,7 +5222,6 @@ ProtocolDecl::ProtocolDecl(DeclContext *DC, SourceLoc ProtocolLoc,
52225222
Bits.ProtocolDecl.ExistentialConformsToSelfValid = false;
52235223
Bits.ProtocolDecl.ExistentialConformsToSelf = false;
52245224
Bits.ProtocolDecl.InheritedProtocolsValid = 0;
5225-
Bits.ProtocolDecl.NumRequirementsInSignature = 0;
52265225
Bits.ProtocolDecl.HasMissingRequirements = false;
52275226
Bits.ProtocolDecl.KnownProtocol = 0;
52285227
Bits.ProtocolDecl.HasAssociatedTypes = 0;
@@ -5438,32 +5437,26 @@ ProtocolDecl::getProtocolDependencies() const {
54385437
None);
54395438
}
54405439

5441-
ArrayRef<Requirement> ProtocolDecl::getRequirementSignature() const {
5440+
RequirementSignature ProtocolDecl::getRequirementSignature() const {
54425441
return evaluateOrDefault(getASTContext().evaluator,
54435442
RequirementSignatureRequest { const_cast<ProtocolDecl *>(this) },
5444-
None);
5443+
RequirementSignature());
54455444
}
54465445

54475446
bool ProtocolDecl::isComputingRequirementSignature() const {
54485447
return getASTContext().evaluator.hasActiveRequest(
54495448
RequirementSignatureRequest{const_cast<ProtocolDecl*>(this)});
54505449
}
54515450

5452-
void ProtocolDecl::setRequirementSignature(ArrayRef<Requirement> requirements) {
5453-
assert(!RequirementSignature && "requirement signature already set");
5454-
if (requirements.empty()) {
5455-
RequirementSignature = reinterpret_cast<Requirement *>(this + 1);
5456-
Bits.ProtocolDecl.NumRequirementsInSignature = 0;
5457-
} else {
5458-
RequirementSignature = requirements.data();
5459-
Bits.ProtocolDecl.NumRequirementsInSignature = requirements.size();
5460-
}
5451+
void ProtocolDecl::setRequirementSignature(RequirementSignature requirementSig) {
5452+
assert(!RequirementSig && "requirement signature already set");
5453+
RequirementSig = requirementSig;
54615454
}
54625455

54635456
void
54645457
ProtocolDecl::setLazyRequirementSignature(LazyMemberLoader *lazyLoader,
54655458
uint64_t requirementSignatureData) {
5466-
assert(!RequirementSignature && "requirement signature already set");
5459+
assert(!RequirementSig && "requirement signature already set");
54675460

54685461
auto contextData = static_cast<LazyProtocolData *>(
54695462
getASTContext().getOrCreateLazyContextData(this, lazyLoader));
@@ -5488,13 +5481,6 @@ ProtocolDecl::setLazyAssociatedTypeMembers(LazyMemberLoader *lazyLoader,
54885481
Bits.ProtocolDecl.HasLazyAssociatedTypes = true;
54895482
}
54905483

5491-
ArrayRef<Requirement> ProtocolDecl::getCachedRequirementSignature() const {
5492-
assert(RequirementSignature &&
5493-
"getting requirement signature before computing it");
5494-
return llvm::makeArrayRef(RequirementSignature,
5495-
Bits.ProtocolDecl.NumRequirementsInSignature);
5496-
}
5497-
54985484
void ProtocolDecl::computeKnownProtocolKind() const {
54995485
auto module = getModuleContext();
55005486
if (module != module->getASTContext().getStdlibModule() &&

0 commit comments

Comments
 (0)