Skip to content

Commit bbbb131

Browse files
committed
Revert "NFC: Remove the now dead ProtocolDecl::existentialTypeSupported()"
This reverts commit eb1bd07.
1 parent f4dabf9 commit bbbb131

File tree

9 files changed

+121
-2
lines changed

9 files changed

+121
-2
lines changed

include/swift/AST/Decl.h

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
519519
IsComputingSemanticMembers : 1
520520
);
521521

522-
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+1+1+8+16,
522+
SWIFT_INLINE_BITFIELD_FULL(ProtocolDecl, NominalTypeDecl, 1+1+1+1+1+1+1+1+1+1+1+8+16,
523523
/// Whether the \c RequiresClass bit is valid.
524524
RequiresClassValid : 1,
525525

@@ -532,6 +532,12 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
532532
/// Whether the existential of this protocol conforms to itself.
533533
ExistentialConformsToSelf : 1,
534534

535+
/// Whether the \c ExistentialTypeSupported bit is valid.
536+
ExistentialTypeSupportedValid : 1,
537+
538+
/// Whether the existential of this protocol can be represented.
539+
ExistentialTypeSupported : 1,
540+
535541
/// True if the protocol has requirements that cannot be satisfied (e.g.
536542
/// because they could not be imported from Objective-C).
537543
HasMissingRequirements : 1,
@@ -4224,6 +4230,21 @@ class ProtocolDecl final : public NominalTypeDecl {
42244230
Bits.ProtocolDecl.ExistentialConformsToSelf = result;
42254231
}
42264232

4233+
/// Returns the cached result of \c existentialTypeSupported or \c None if it
4234+
/// hasn't yet been computed.
4235+
Optional<bool> getCachedExistentialTypeSupported() {
4236+
if (Bits.ProtocolDecl.ExistentialTypeSupportedValid)
4237+
return Bits.ProtocolDecl.ExistentialTypeSupported;
4238+
4239+
return None;
4240+
}
4241+
4242+
/// Caches the result of \c existentialTypeSupported
4243+
void setCachedExistentialTypeSupported(bool supported) {
4244+
Bits.ProtocolDecl.ExistentialTypeSupportedValid = true;
4245+
Bits.ProtocolDecl.ExistentialTypeSupported = supported;
4246+
}
4247+
42274248
bool hasLazyRequirementSignature() const {
42284249
return Bits.ProtocolDecl.HasLazyRequirementSignature;
42294250
}
@@ -4237,6 +4258,7 @@ class ProtocolDecl final : public NominalTypeDecl {
42374258
friend class RequirementSignatureRequestRQM;
42384259
friend class ProtocolRequiresClassRequest;
42394260
friend class ExistentialConformsToSelfRequest;
4261+
friend class ExistentialTypeSupportedRequest;
42404262
friend class InheritedProtocolsRequest;
42414263

42424264
public:
@@ -4325,6 +4347,12 @@ class ProtocolDecl final : public NominalTypeDecl {
43254347
/// contain 'Self' in 'parameter' or 'other' position.
43264348
bool isAvailableInExistential(const ValueDecl *decl) const;
43274349

4350+
/// Determine whether we are allowed to refer to an existential type
4351+
/// conforming to this protocol. This is only permitted if the types of
4352+
/// all the members do not contain any associated types, and do not
4353+
/// contain 'Self' in 'parameter' or 'other' position.
4354+
bool existentialTypeSupported() const;
4355+
43284356
/// Returns a list of protocol requirements that must be assessed to
43294357
/// determine a concrete's conformance effect polymorphism kind.
43304358
PolymorphicEffectRequirementList getPolymorphicEffectRequirements(

include/swift/AST/TypeCheckRequests.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,32 @@ class ExistentialConformsToSelfRequest :
287287
void cacheResult(bool value) const;
288288
};
289289

290+
/// Determine whether we are allowed to refer to an existential type conforming
291+
/// to this protocol.
292+
class ExistentialTypeSupportedRequest :
293+
public SimpleRequest<ExistentialTypeSupportedRequest,
294+
bool(ProtocolDecl *),
295+
RequestFlags::SeparatelyCached> {
296+
public:
297+
using SimpleRequest::SimpleRequest;
298+
299+
private:
300+
friend SimpleRequest;
301+
302+
// Evaluation.
303+
bool evaluate(Evaluator &evaluator, ProtocolDecl *decl) const;
304+
305+
public:
306+
// Cycle handling.
307+
void diagnoseCycle(DiagnosticEngine &diags) const;
308+
void noteCycleStep(DiagnosticEngine &diags) const;
309+
310+
// Separate caching.
311+
bool isCached() const { return true; }
312+
Optional<bool> getCachedResult() const;
313+
void cacheResult(bool value) const;
314+
};
315+
290316
class PolymorphicEffectRequirementsRequest :
291317
public SimpleRequest<PolymorphicEffectRequirementsRequest,
292318
PolymorphicEffectRequirementList(EffectKind, ProtocolDecl *),

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ SWIFT_REQUEST(TypeChecker, EnumRawTypeRequest,
9292
Type(EnumDecl *), Cached, NoLocationInfo)
9393
SWIFT_REQUEST(TypeChecker, ExistentialConformsToSelfRequest,
9494
bool(ProtocolDecl *), SeparatelyCached, NoLocationInfo)
95+
SWIFT_REQUEST(TypeChecker, ExistentialTypeSupportedRequest,
96+
bool(ProtocolDecl *), SeparatelyCached, NoLocationInfo)
9597
SWIFT_REQUEST(TypeChecker, ExtendedTypeRequest, Type(ExtensionDecl *), Cached,
9698
NoLocationInfo)
9799
SWIFT_REQUEST(TypeChecker, ResultBuilderTypeRequest, Type(ValueDecl *),

lib/AST/Decl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5258,6 +5258,11 @@ bool ProtocolDecl::isAvailableInExistential(const ValueDecl *decl) const {
52585258
return true;
52595259
}
52605260

5261+
bool ProtocolDecl::existentialTypeSupported() const {
5262+
return evaluateOrDefault(getASTContext().evaluator,
5263+
ExistentialTypeSupportedRequest{const_cast<ProtocolDecl *>(this)}, true);
5264+
}
5265+
52615266
StringRef ProtocolDecl::getObjCRuntimeName(
52625267
llvm::SmallVectorImpl<char> &buffer) const {
52635268
// If there is an 'objc' attribute with a name, use that name.

lib/AST/TypeCheckRequests.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,31 @@ void ExistentialConformsToSelfRequest::cacheResult(bool value) const {
249249
decl->setCachedExistentialConformsToSelf(value);
250250
}
251251

252+
//----------------------------------------------------------------------------//
253+
// existentialTypeSupported computation.
254+
//----------------------------------------------------------------------------//
255+
256+
void ExistentialTypeSupportedRequest::diagnoseCycle(DiagnosticEngine &diags) const {
257+
auto decl = std::get<0>(getStorage());
258+
diags.diagnose(decl, diag::circular_protocol_def, decl->getName());
259+
}
260+
261+
void ExistentialTypeSupportedRequest::noteCycleStep(DiagnosticEngine &diags) const {
262+
auto requirement = std::get<0>(getStorage());
263+
diags.diagnose(requirement, diag::kind_declname_declared_here,
264+
DescriptiveDeclKind::Protocol, requirement->getName());
265+
}
266+
267+
Optional<bool> ExistentialTypeSupportedRequest::getCachedResult() const {
268+
auto decl = std::get<0>(getStorage());
269+
return decl->getCachedExistentialTypeSupported();
270+
}
271+
272+
void ExistentialTypeSupportedRequest::cacheResult(bool value) const {
273+
auto decl = std::get<0>(getStorage());
274+
decl->setCachedExistentialTypeSupported(value);
275+
}
276+
252277
//----------------------------------------------------------------------------//
253278
// isFinal computation.
254279
//----------------------------------------------------------------------------//

lib/Sema/TypeCheckDecl.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,34 @@ ExistentialConformsToSelfRequest::evaluate(Evaluator &evaluator,
666666
return true;
667667
}
668668

669+
bool
670+
ExistentialTypeSupportedRequest::evaluate(Evaluator &evaluator,
671+
ProtocolDecl *decl) const {
672+
// ObjC protocols can always be existential.
673+
if (decl->isObjC())
674+
return true;
675+
676+
for (auto member : decl->getMembers()) {
677+
// Existential types cannot be used if the protocol has an associated type.
678+
if (isa<AssociatedTypeDecl>(member))
679+
return false;
680+
681+
// For value members, look at their type signatures.
682+
if (auto valueMember = dyn_cast<ValueDecl>(member)) {
683+
if (!decl->isAvailableInExistential(valueMember))
684+
return false;
685+
}
686+
}
687+
688+
// Check whether all of the inherited protocols support existential types.
689+
for (auto proto : decl->getInheritedProtocols()) {
690+
if (!proto->existentialTypeSupported())
691+
return false;
692+
}
693+
694+
return true;
695+
}
696+
669697
bool
670698
IsFinalRequest::evaluate(Evaluator &evaluator, ValueDecl *decl) const {
671699
if (isa<ClassDecl>(decl))

lib/Serialization/Deserialization.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3564,13 +3564,14 @@ class DeclDeserializer {
35643564
StringRef blobData) {
35653565
IdentifierID nameID;
35663566
DeclContextID contextID;
3567-
bool isImplicit, isClassBounded, isObjC;
3567+
bool isImplicit, isClassBounded, isObjC, existentialTypeSupported;
35683568
uint8_t rawAccessLevel;
35693569
unsigned numInheritedTypes;
35703570
ArrayRef<uint64_t> rawInheritedAndDependencyIDs;
35713571

35723572
decls_block::ProtocolLayout::readRecord(scratch, nameID, contextID,
35733573
isImplicit, isClassBounded, isObjC,
3574+
existentialTypeSupported,
35743575
rawAccessLevel, numInheritedTypes,
35753576
rawInheritedAndDependencyIDs);
35763577

@@ -3596,6 +3597,8 @@ class DeclDeserializer {
35963597

35973598
ctx.evaluator.cacheOutput(ProtocolRequiresClassRequest{proto},
35983599
std::move(isClassBounded));
3600+
ctx.evaluator.cacheOutput(ExistentialTypeSupportedRequest{proto},
3601+
std::move(existentialTypeSupported));
35993602

36003603
if (auto accessLevel = getActualAccessLevel(rawAccessLevel))
36013604
proto->setAccess(*accessLevel);

lib/Serialization/ModuleFormat.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1292,6 +1292,7 @@ namespace decls_block {
12921292
BCFixed<1>, // implicit flag
12931293
BCFixed<1>, // class-bounded?
12941294
BCFixed<1>, // objc?
1295+
BCFixed<1>, // existential-type-supported?
12951296
AccessLevelField, // access level
12961297
BCVBR<4>, // number of inherited types
12971298
BCArray<TypeIDField> // inherited types, followed by dependency types

lib/Serialization/Serialization.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3630,6 +3630,7 @@ class Serializer::DeclSerializer : public DeclVisitor<DeclSerializer> {
36303630
const_cast<ProtocolDecl *>(proto)
36313631
->requiresClass(),
36323632
proto->isObjC(),
3633+
proto->existentialTypeSupported(),
36333634
rawAccessLevel, numInherited,
36343635
inheritedAndDependencyTypes);
36353636

0 commit comments

Comments
 (0)