Skip to content

Commit cfae7bb

Browse files
committed
Avoid cycles when computing a requirement signature
Replace most remaining uses of isRequirementSignatureComputed by isRequirementSignatureComputing which uses Evaluator::hasActiveRequest to detect if the requirements are currently being computed.
1 parent 3cb1b6a commit cfae7bb

File tree

4 files changed

+10
-2
lines changed

4 files changed

+10
-2
lines changed

include/swift/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4305,6 +4305,9 @@ class ProtocolDecl final : public NominalTypeDecl {
43054305
/// requirements listed here become entries in the witness table.
43064306
ArrayRef<Requirement> getRequirementSignature() const;
43074307

4308+
/// Is the requirement signature currently being computed?
4309+
bool isComputingRequirementSignature() const;
4310+
43084311
/// Has the requirement signature been computed yet?
43094312
bool isRequirementSignatureComputed() const {
43104313
return RequirementSignature != nullptr;

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ class GenericSignatureBuilder::RequirementSource final
10561056
WrittenRequirementLoc writtenReqLoc)
10571057
: kind(kind), storageKind(StorageKind::StoredType),
10581058
hasTrailingWrittenRequirementLoc(!writtenReqLoc.isNull()),
1059-
usesRequirementSignature(protocol->isRequirementSignatureComputed()),
1059+
usesRequirementSignature(!protocol->isComputingRequirementSignature()),
10601060
parent(parent) {
10611061
assert((static_cast<bool>(parent) != isRootKind(kind)) &&
10621062
"Root RequirementSource should not have parent (or vice versa)");

lib/AST/Decl.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4575,6 +4575,11 @@ ArrayRef<Requirement> ProtocolDecl::getRequirementSignature() const {
45754575
None);
45764576
}
45774577

4578+
bool ProtocolDecl::isComputingRequirementSignature() const {
4579+
return getASTContext().evaluator.hasActiveRequest(
4580+
RequirementSignatureRequest{const_cast<ProtocolDecl*>(this)});
4581+
}
4582+
45784583
void ProtocolDecl::setRequirementSignature(ArrayRef<Requirement> requirements) {
45794584
assert(!RequirementSignature && "requirement signature already set");
45804585
if (requirements.empty()) {

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4107,7 +4107,7 @@ ConstraintResult GenericSignatureBuilder::expandConformanceRequirement(
41074107
// Use the requirement signature to avoid rewalking the entire protocol. This
41084108
// cannot compute the requirement signature directly, because that may be
41094109
// infinitely recursive: this code is also used to construct it.
4110-
if (proto->isRequirementSignatureComputed()) {
4110+
if (!proto->isComputingRequirementSignature()) {
41114111
auto innerSource =
41124112
FloatingRequirementSource::viaProtocolRequirement(source, proto,
41134113
/*inferred=*/false);

0 commit comments

Comments
 (0)