Skip to content

Commit c699553

Browse files
committed
Sema: Fix upcoming request cycle in ConformanceChecker::resolveSingleWitness()
1 parent 5866d8a commit c699553

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

lib/Sema/TypeCheckProtocol.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4815,16 +4815,35 @@ void ConformanceChecker::resolveSingleWitness(ValueDecl *requirement) {
48154815
if (!requirement->isProtocolRequirement())
48164816
return;
48174817

4818+
auto &evaluator = getASTContext().evaluator;
4819+
48184820
// Resolve the type witnesses for all associated types referenced by
48194821
// the requirement. If any are erroneous, don't bother resolving the
48204822
// witness.
4821-
auto referenced = evaluateOrDefault(getASTContext().evaluator,
4823+
auto referenced = evaluateOrDefault(evaluator,
48224824
ReferencedAssociatedTypesRequest{requirement},
48234825
TinyPtrVector<AssociatedTypeDecl *>());
48244826
for (auto assocType : referenced) {
4827+
// There's a weird cycle break here. If we're in the middle of resolving
4828+
// type witnesses, we return from here without recording a value witness.
4829+
// This is handled by not caching the result, and the conformance checker
4830+
// will then attempt to resolve the value witness later.
4831+
if (evaluator.hasActiveRequest(TypeWitnessRequest{Conformance, assocType})) {
4832+
return;
4833+
}
4834+
4835+
if (!Conformance->hasTypeWitness(assocType)) {
4836+
if (evaluator.hasActiveRequest(ResolveTypeWitnessesRequest{Conformance})) {
4837+
return;
4838+
}
4839+
}
4840+
48254841
auto typeWitness = Conformance->getTypeWitness(assocType);
48264842
if (!typeWitness)
48274843
return;
4844+
4845+
// However, if the type witness was already resolved and it has an error
4846+
// type, mark the conformance invalid and give up.
48284847
if (typeWitness->hasError()) {
48294848
Conformance->setInvalid();
48304849
return;

0 commit comments

Comments
 (0)