@@ -4815,16 +4815,35 @@ void ConformanceChecker::resolveSingleWitness(ValueDecl *requirement) {
4815
4815
if (!requirement->isProtocolRequirement ())
4816
4816
return ;
4817
4817
4818
+ auto &evaluator = getASTContext ().evaluator ;
4819
+
4818
4820
// Resolve the type witnesses for all associated types referenced by
4819
4821
// the requirement. If any are erroneous, don't bother resolving the
4820
4822
// witness.
4821
- auto referenced = evaluateOrDefault (getASTContext (). evaluator ,
4823
+ auto referenced = evaluateOrDefault (evaluator,
4822
4824
ReferencedAssociatedTypesRequest{requirement},
4823
4825
TinyPtrVector<AssociatedTypeDecl *>());
4824
4826
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
+
4825
4841
auto typeWitness = Conformance->getTypeWitness (assocType);
4826
4842
if (!typeWitness)
4827
4843
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.
4828
4847
if (typeWitness->hasError ()) {
4829
4848
Conformance->setInvalid ();
4830
4849
return ;
0 commit comments