@@ -450,10 +450,16 @@ static Constraint *determineBestChoicesInContext(
450
450
// - Array-to-pointer conversion
451
451
// - Value to existential conversion
452
452
// - 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 > {
457
463
auto areEqual = [&options](Type a, Type b) {
458
464
// Double<->CGFloat implicit conversion support for literals
459
465
// only since in this case the conversion might not result in
@@ -527,10 +533,12 @@ static Constraint *determineBestChoicesInContext(
527
533
528
534
// Check protocol requirement(s) if this parameter is a
529
535
// 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>()) {
534
542
auto protocolRequirements =
535
543
genericSig->getRequiredProtocols (paramType);
536
544
if (llvm::all_of (protocolRequirements, [&](ProtocolDecl *protocol) {
@@ -547,6 +555,10 @@ static Constraint *determineBestChoicesInContext(
547
555
return 0 ;
548
556
}
549
557
558
+ // Cannot match anything but generic type parameters here.
559
+ if (!paramType->is <GenericTypeParamType>())
560
+ return std::nullopt;
561
+
550
562
// If the candidate type is fully resolved, let's check all of
551
563
// the requirements that are associated with the corresponding
552
564
// parameter, if all of them are satisfied this candidate is
@@ -718,10 +730,15 @@ static Constraint *determineBestChoicesInContext(
718
730
if (favorExactMatchesOnly)
719
731
options |= MatchFlag::ExactOnly;
720
732
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 ());
725
742
continue ;
726
743
}
727
744
0 commit comments