@@ -3997,6 +3997,36 @@ ResolveTypeWitnessesRequest::evaluate(Evaluator &evaluator,
3997
3997
return evaluator::SideEffect ();
3998
3998
}
3999
3999
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
+
4000
4030
TypeWitnessAndDecl
4001
4031
TypeWitnessRequest::evaluate (Evaluator &eval,
4002
4032
NormalProtocolConformance *conformance,
@@ -4008,8 +4038,30 @@ TypeWitnessRequest::evaluate(Evaluator &eval,
4008
4038
break ;
4009
4039
4010
4040
case ResolveWitnessResult::Missing: {
4011
- // The type witness is still missing. Resolve all of the type witnesses.
4012
4041
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.
4013
4065
evaluateOrDefault (ctx.evaluator ,
4014
4066
ResolveTypeWitnessesRequest{conformance},
4015
4067
evaluator::SideEffect ());
0 commit comments