Skip to content

Commit ddfc441

Browse files
authored
Merge pull request #27148 from xedin/rdar-55314724-5.1-08-28
[5.1 08/28][CSRanking] Always rank key path dynamic member choices lower than no…
2 parents 28c0468 + 6eec2a6 commit ddfc441

File tree

2 files changed

+40
-8
lines changed

2 files changed

+40
-8
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -880,17 +880,27 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
880880
continue;
881881
}
882882

883-
// Dynamic member lookup through a keypath is better than one using string
884-
// because it carries more type information.
885-
if (choice1.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup &&
886-
choice2.getKind() == OverloadChoiceKind::DynamicMemberLookup) {
887-
score1 += weight;
883+
if (choice1.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup) {
884+
if (choice2.getKind() == OverloadChoiceKind::DynamicMemberLookup)
885+
// Dynamic member lookup through a keypath is better than one using
886+
// string because it carries more type information.
887+
score1 += weight;
888+
else
889+
// Otherwise let's prefer non-dynamic declaration.
890+
score2 += weight;
891+
888892
continue;
889893
}
890894

891-
if (choice1.getKind() == OverloadChoiceKind::DynamicMemberLookup &&
892-
choice2.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup) {
893-
score2 += weight;
895+
if (choice2.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup) {
896+
if (choice1.getKind() == OverloadChoiceKind::DynamicMemberLookup)
897+
// Dynamic member lookup through a keypath is better than one using
898+
// string because it carries more type information.
899+
score2 += weight;
900+
else
901+
// Otherwise let's prefer non-dynamic declaration.
902+
score1 += weight;
903+
894904
continue;
895905
}
896906

test/Constraints/keypath_dynamic_member_lookup.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,3 +328,25 @@ func rdar52779809(_ ref1: Ref<S>, _ ref2: Ref<Q>) {
328328
// CHECK: function_ref @$s29keypath_dynamic_member_lookup3RefV0B6Memberqd__s7KeyPathCyxqd__G_tcluig
329329
_ = ref2.bar // Ok
330330
}
331+
332+
// SR-11465 - Ambiguity in expression which matches both dynamic member lookup and declaration from constrained extension
333+
334+
@dynamicMemberLookup
335+
struct SR_11465<RawValue> {
336+
var rawValue: RawValue
337+
338+
subscript<Subject>(dynamicMember keyPath: KeyPath<RawValue, Subject>) -> Subject {
339+
rawValue[keyPath: keyPath]
340+
}
341+
}
342+
343+
extension SR_11465: Hashable, Equatable where RawValue: Hashable {
344+
func hash(into hasher: inout Hasher) {
345+
hasher.combine(self.rawValue)
346+
}
347+
}
348+
349+
func test_constrained_ext_vs_dynamic_member() {
350+
// CHECK: function_ref @$s29keypath_dynamic_member_lookup8SR_11465VAASHRzlE9hashValueSivg
351+
_ = SR_11465<Int>(rawValue: 1).hashValue // Ok, keep choice from constrained extension
352+
}

0 commit comments

Comments
 (0)