Skip to content

Commit e0160a4

Browse files
authored
Merge pull request #27146 from xedin/dynamic-member-vs-contrained-ext
[CSRanking] Always rank key path dynamic member choices lower than no…
2 parents cd8fddd + 868afc6 commit e0160a4

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -822,17 +822,27 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
822822
continue;
823823
}
824824

825-
// Dynamic member lookup through a keypath is better than one using string
826-
// because it carries more type information.
827-
if (choice1.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup &&
828-
choice2.getKind() == OverloadChoiceKind::DynamicMemberLookup) {
829-
score1 += weight;
825+
if (choice1.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup) {
826+
if (choice2.getKind() == OverloadChoiceKind::DynamicMemberLookup)
827+
// Dynamic member lookup through a keypath is better than one using
828+
// string because it carries more type information.
829+
score1 += weight;
830+
else
831+
// Otherwise let's prefer non-dynamic declaration.
832+
score2 += weight;
833+
830834
continue;
831835
}
832836

833-
if (choice1.getKind() == OverloadChoiceKind::DynamicMemberLookup &&
834-
choice2.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup) {
835-
score2 += weight;
837+
if (choice2.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup) {
838+
if (choice1.getKind() == OverloadChoiceKind::DynamicMemberLookup)
839+
// Dynamic member lookup through a keypath is better than one using
840+
// string because it carries more type information.
841+
score2 += weight;
842+
else
843+
// Otherwise let's prefer non-dynamic declaration.
844+
score1 += weight;
845+
836846
continue;
837847
}
838848

test/Constraints/keypath_dynamic_member_lookup.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -367,3 +367,26 @@ func make_sure_delayed_keypath_dynamic_member_works() {
367367
}
368368
}
369369
}
370+
371+
372+
// SR-11465 - Ambiguity in expression which matches both dynamic member lookup and declaration from constrained extension
373+
374+
@dynamicMemberLookup
375+
struct SR_11465<RawValue> {
376+
var rawValue: RawValue
377+
378+
subscript<Subject>(dynamicMember keyPath: KeyPath<RawValue, Subject>) -> Subject {
379+
rawValue[keyPath: keyPath]
380+
}
381+
}
382+
383+
extension SR_11465: Hashable, Equatable where RawValue: Hashable {
384+
func hash(into hasher: inout Hasher) {
385+
hasher.combine(self.rawValue)
386+
}
387+
}
388+
389+
func test_constrained_ext_vs_dynamic_member() {
390+
// CHECK: function_ref @$s29keypath_dynamic_member_lookup8SR_11465VAASHRzlE9hashValueSivg
391+
_ = SR_11465<Int>(rawValue: 1).hashValue // Ok, keep choice from constrained extension
392+
}

0 commit comments

Comments
 (0)