@@ -3997,6 +3997,36 @@ ResolveTypeWitnessesRequest::evaluate(Evaluator &evaluator,
39973997 return evaluator::SideEffect ();
39983998}
39993999
4000+ static NormalProtocolConformance *
4001+ getBetterConformanceForResolvingTypeWitnesses (NormalProtocolConformance *conformance,
4002+ AssociatedTypeDecl *requirement) {
4003+ auto *dc = conformance->getDeclContext ();
4004+ assert (dc->getParentSourceFile () && " What are you doing?" );
4005+ auto *proto = conformance->getProtocol ();
4006+
4007+ IterableDeclContext *idc;
4008+ if (auto *extensionDecl = dyn_cast<ExtensionDecl>(dc))
4009+ idc = extensionDecl;
4010+ else
4011+ idc = cast<NominalTypeDecl>(dc);
4012+
4013+ auto otherConformances = idc->getLocalConformances (ConformanceLookupKind::NonStructural);
4014+ for (auto *otherConformance : otherConformances) {
4015+ auto *otherNormal = dyn_cast<NormalProtocolConformance>(
4016+ otherConformance->getRootConformance ());
4017+ if (otherNormal == nullptr )
4018+ continue ;
4019+
4020+ auto *otherProto = otherNormal->getProtocol ();
4021+ if (otherProto->inheritsFrom (proto) &&
4022+ otherProto->getAssociatedType (requirement->getName ())) {
4023+ return otherNormal;
4024+ }
4025+ }
4026+
4027+ return conformance;
4028+ }
4029+
40004030TypeWitnessAndDecl
40014031TypeWitnessRequest::evaluate (Evaluator &eval,
40024032 NormalProtocolConformance *conformance,
@@ -4008,8 +4038,30 @@ TypeWitnessRequest::evaluate(Evaluator &eval,
40084038 break ;
40094039
40104040 case ResolveWitnessResult::Missing: {
4011- // The type witness is still missing. Resolve all of the type witnesses.
40124041 auto &ctx = requirement->getASTContext ();
4042+
4043+ if (ctx.LangOpts .EnableExperimentalAssociatedTypeInference ) {
4044+ // Let's see if there is a better conformance we can perform associated
4045+ // type inference on.
4046+ auto *better = getBetterConformanceForResolvingTypeWitnesses (
4047+ conformance, requirement);
4048+
4049+ if (better != conformance &&
4050+ !ctx.evaluator .hasActiveRequest (ResolveTypeWitnessesRequest{better})) {
4051+ // Let's try to resolve type witnesses in the better conformance.
4052+ evaluateOrDefault (ctx.evaluator ,
4053+ ResolveTypeWitnessesRequest{better},
4054+ evaluator::SideEffect ());
4055+
4056+ // Check whether the above populated the type witness of our conformance.
4057+ auto known = conformance->TypeWitnesses .find (requirement);
4058+ if (known != conformance->TypeWitnesses .end ())
4059+ return known->second ;
4060+ }
4061+ }
4062+
4063+ // The type witness is still missing. Resolve all of the type witnesses
4064+ // in this conformance.
40134065 evaluateOrDefault (ctx.evaluator ,
40144066 ResolveTypeWitnessesRequest{conformance},
40154067 evaluator::SideEffect ());
0 commit comments