Skip to content

Commit dcadc0d

Browse files
committed
AST: Introduce ProtocolDecl::getPrimaryAssociatedType()
1 parent ab2935a commit dcadc0d

File tree

5 files changed

+45
-0
lines changed

5 files changed

+45
-0
lines changed

include/swift/AST/Decl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4372,6 +4372,11 @@ class ProtocolDecl final : public NominalTypeDecl {
43724372
/// a protocol having nested types (ObjC protocols).
43734373
ArrayRef<AssociatedTypeDecl *> getAssociatedTypeMembers() const;
43744374

4375+
/// Returns the primary associated type, or nullptr if there isn't one. This is
4376+
/// the associated type that is parametrized with a same-type requirement in a
4377+
/// parametrized protocol type of the form SomeProtocol<SomeArgType>.
4378+
AssociatedTypeDecl *getPrimaryAssociatedType() const;
4379+
43754380
/// Returns a protocol requirement with the given name, or nullptr if the
43764381
/// name has multiple overloads, or no overloads at all.
43774382
ValueDecl *getSingleRequirement(DeclName name) const;

include/swift/AST/TypeCheckRequests.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,26 @@ class ExistentialRequiresAnyRequest :
313313
void cacheResult(bool value) const;
314314
};
315315

316+
/// Find the primary associated type of the given protocol.
317+
class PrimaryAssociatedTypeRequest :
318+
public SimpleRequest<PrimaryAssociatedTypeRequest,
319+
AssociatedTypeDecl *(ProtocolDecl *),
320+
RequestFlags::Cached> {
321+
public:
322+
using SimpleRequest::SimpleRequest;
323+
324+
private:
325+
friend SimpleRequest;
326+
327+
// Evaluation.
328+
AssociatedTypeDecl *
329+
evaluate(Evaluator &evaluator, ProtocolDecl *decl) const;
330+
331+
public:
332+
// Caching.
333+
bool isCached() const { return true; }
334+
};
335+
316336
class PolymorphicEffectRequirementsRequest :
317337
public SimpleRequest<PolymorphicEffectRequirementsRequest,
318338
PolymorphicEffectRequirementList(EffectKind, ProtocolDecl *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,9 @@ SWIFT_REQUEST(TypeChecker, PropertyWrapperTypeInfoRequest,
233233
NoLocationInfo)
234234
SWIFT_REQUEST(TypeChecker, ProtocolRequiresClassRequest, bool(ProtocolDecl *),
235235
SeparatelyCached, NoLocationInfo)
236+
SWIFT_REQUEST(TypeChecker, PrimaryAssociatedTypeRequest,
237+
AssociatedTypeDecl *(ProtocolDecl *),
238+
Cached, NoLocationInfo)
236239
SWIFT_REQUEST(TypeChecker, RequirementRequest,
237240
Requirement(WhereClauseOwner, unsigned, TypeResolutionStage),
238241
Cached, HasNearestLocation)

lib/AST/Decl.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5284,6 +5284,12 @@ bool ProtocolDecl::existentialRequiresAny() const {
52845284
ExistentialRequiresAnyRequest{const_cast<ProtocolDecl *>(this)}, true);
52855285
}
52865286

5287+
AssociatedTypeDecl *ProtocolDecl::getPrimaryAssociatedType() const {
5288+
return evaluateOrDefault(getASTContext().evaluator,
5289+
PrimaryAssociatedTypeRequest{const_cast<ProtocolDecl *>(this)},
5290+
nullptr);
5291+
}
5292+
52875293
StringRef ProtocolDecl::getObjCRuntimeName(
52885294
llvm::SmallVectorImpl<char> &buffer) const {
52895295
// If there is an 'objc' attribute with a name, use that name.

lib/Sema/TypeCheckDecl.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,17 @@ ExistentialRequiresAnyRequest::evaluate(Evaluator &evaluator,
694694
return false;
695695
}
696696

697+
AssociatedTypeDecl *
698+
PrimaryAssociatedTypeRequest::evaluate(Evaluator &evaluator,
699+
ProtocolDecl *decl) const {
700+
for (auto *assocType : decl->getAssociatedTypeMembers()) {
701+
if (assocType->getAttrs().hasAttribute<PrimaryAssociatedTypeAttr>())
702+
return assocType;
703+
}
704+
705+
return nullptr;
706+
}
707+
697708
bool
698709
IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
699710
if (isa<ClassDecl>(decl))

0 commit comments

Comments
 (0)