Skip to content

Commit 00a4629

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

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
@@ -520,7 +520,7 @@ class alignas(1 << DeclAlignInBits) Decl : public ASTAllocated<Decl> {
520520
IsComputingSemanticMembers : 1
521521
);
522522

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

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

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

4253+
/// Returns the cached result of \c existentialTypeSupported or \c None if it
4254+
/// hasn't yet been computed.
4255+
Optional<bool> getCachedExistentialTypeSupported() {
4256+
if (Bits.ProtocolDecl.ExistentialTypeSupportedValid)
4257+
return Bits.ProtocolDecl.ExistentialTypeSupported;
4258+
4259+
return None;
4260+
}
4261+
4262+
/// Caches the result of \c existentialTypeSupported
4263+
void setCachedExistentialTypeSupported(bool supported) {
4264+
Bits.ProtocolDecl.ExistentialTypeSupportedValid = true;
4265+
Bits.ProtocolDecl.ExistentialTypeSupported = supported;
4266+
}
4267+
42474268
bool hasLazyRequirementSignature() const {
42484269
return Bits.ProtocolDecl.HasLazyRequirementSignature;
42494270
}
@@ -4257,6 +4278,7 @@ class ProtocolDecl final : public NominalTypeDecl {
42574278
friend class RequirementSignatureRequestRQM;
42584279
friend class ProtocolRequiresClassRequest;
42594280
friend class ExistentialConformsToSelfRequest;
4281+
friend class ExistentialTypeSupportedRequest;
42604282
friend class InheritedProtocolsRequest;
42614283

42624284
public:
@@ -4345,6 +4367,12 @@ class ProtocolDecl final : public NominalTypeDecl {
43454367
/// contain 'Self' in 'parameter' or 'other' position.
43464368
bool isAvailableInExistential(const ValueDecl *decl) const;
43474369

4370+
/// Determine whether we are allowed to refer to an existential type
4371+
/// conforming to this protocol. This is only permitted if the types of
4372+
/// all the members do not contain any associated types, and do not
4373+
/// contain 'Self' in 'parameter' or 'other' position.
4374+
bool existentialTypeSupported() const;
4375+
43484376
/// Returns a list of protocol requirements that must be assessed to
43494377
/// determine a concrete's conformance effect polymorphism kind.
43504378
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
@@ -5266,6 +5266,11 @@ bool ProtocolDecl::isAvailableInExistential(const ValueDecl *decl) const {
52665266
return true;
52675267
}
52685268

5269+
bool ProtocolDecl::existentialTypeSupported() const {
5270+
return evaluateOrDefault(getASTContext().evaluator,
5271+
ExistentialTypeSupportedRequest{const_cast<ProtocolDecl *>(this)}, true);
5272+
}
5273+
52695274
StringRef ProtocolDecl::getObjCRuntimeName(
52705275
llvm::SmallVectorImpl<char> &buffer) const {
52715276
// 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)