Skip to content

Commit 62f7578

Browse files
committed
Sema: Fix upcoming request cycle in ConformanceChecker::resolveSingleWitness()
1 parent cf8269a commit 62f7578

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
@@ -4816,16 +4816,35 @@ void ConformanceChecker::resolveSingleWitness(ValueDecl *requirement) {
48164816
if (!requirement->isProtocolRequirement())
48174817
return;
48184818

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

0 commit comments

Comments
 (0)