@@ -450,10 +450,16 @@ static Constraint *determineBestChoicesInContext(
450450 // - Array-to-pointer conversion
451451 // - Value to existential conversion
452452 // - Exact match on top-level types
453- std::function<double (GenericSignature, Type, Type, MatchOptions)>
454- scoreCandidateMatch = [&](GenericSignature genericSig,
455- Type candidateType, Type paramType,
456- MatchOptions options) -> double {
453+ //
454+ // In situations when it's not possible to determine whether a candidate
455+ // type matches a parameter type (i.e. when partially resolved generic
456+ // types are matched) this function is going to produce \c std::nullopt
457+ // instead of `0` that indicates "not a match".
458+ std::function<std::optional<double >(GenericSignature, Type, Type,
459+ MatchOptions)>
460+ scoreCandidateMatch =
461+ [&](GenericSignature genericSig, Type candidateType, Type paramType,
462+ MatchOptions options) -> std::optional<double > {
457463 auto areEqual = [&options](Type a, Type b) {
458464 // Double<->CGFloat implicit conversion support for literals
459465 // only since in this case the conversion might not result in
@@ -527,10 +533,12 @@ static Constraint *determineBestChoicesInContext(
527533
528534 // Check protocol requirement(s) if this parameter is a
529535 // generic parameter type.
530- if (genericSig && paramType->is <GenericTypeParamType>()) {
531- // If candidate is not fully resolved, check conformances only
532- // and lower the score.
533- if (candidateType->hasTypeVariable ()) {
536+ if (genericSig && paramType->isTypeParameter ()) {
537+ // If candidate is not fully resolved or is matched against a
538+ // dependent member type (i.e. `Self.T`), let's check conformances
539+ // only and lower the score.
540+ if (candidateType->hasTypeVariable () ||
541+ paramType->is <DependentMemberType>()) {
534542 auto protocolRequirements =
535543 genericSig->getRequiredProtocols (paramType);
536544 if (llvm::all_of (protocolRequirements, [&](ProtocolDecl *protocol) {
@@ -547,6 +555,10 @@ static Constraint *determineBestChoicesInContext(
547555 return 0 ;
548556 }
549557
558+ // Cannot match anything but generic type parameters here.
559+ if (!paramType->is <GenericTypeParamType>())
560+ return std::nullopt ;
561+
550562 // If the candidate type is fully resolved, let's check all of
551563 // the requirements that are associated with the corresponding
552564 // parameter, if all of them are satisfied this candidate is
@@ -718,10 +730,15 @@ static Constraint *determineBestChoicesInContext(
718730 if (favorExactMatchesOnly)
719731 options |= MatchFlag::ExactOnly;
720732
721- auto score = scoreCandidateMatch (genericSig, candidateType,
722- paramType, options);
723- if (score > 0 ) {
724- bestCandidateScore = std::max (bestCandidateScore, score);
733+ auto candidateScore = scoreCandidateMatch (
734+ genericSig, candidateType, paramType, options);
735+
736+ if (!candidateScore)
737+ continue ;
738+
739+ if (candidateScore > 0 ) {
740+ bestCandidateScore =
741+ std::max (bestCandidateScore, candidateScore.value ());
725742 continue ;
726743 }
727744
0 commit comments