@@ -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