Skip to content

Commit

Permalink
Merge pull request apple#27146 from xedin/dynamic-member-vs-contraine…
Browse files Browse the repository at this point in the history
…d-ext

[CSRanking] Always rank key path dynamic member choices lower than no…
  • Loading branch information
xedin committed Sep 13, 2019
2 parents cd8fddd + 868afc6 commit e0160a4
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 8 deletions.
26 changes: 18 additions & 8 deletions lib/Sema/CSRanking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -822,17 +822,27 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
continue;
}

// Dynamic member lookup through a keypath is better than one using string
// because it carries more type information.
if (choice1.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup &&
choice2.getKind() == OverloadChoiceKind::DynamicMemberLookup) {
score1 += weight;
if (choice1.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup) {
if (choice2.getKind() == OverloadChoiceKind::DynamicMemberLookup)
// Dynamic member lookup through a keypath is better than one using
// string because it carries more type information.
score1 += weight;
else
// Otherwise let's prefer non-dynamic declaration.
score2 += weight;

continue;
}

if (choice1.getKind() == OverloadChoiceKind::DynamicMemberLookup &&
choice2.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup) {
score2 += weight;
if (choice2.getKind() == OverloadChoiceKind::KeyPathDynamicMemberLookup) {
if (choice1.getKind() == OverloadChoiceKind::DynamicMemberLookup)
// Dynamic member lookup through a keypath is better than one using
// string because it carries more type information.
score2 += weight;
else
// Otherwise let's prefer non-dynamic declaration.
score1 += weight;

continue;
}

Expand Down
23 changes: 23 additions & 0 deletions test/Constraints/keypath_dynamic_member_lookup.swift
Original file line number Diff line number Diff line change
Expand Up @@ -367,3 +367,26 @@ func make_sure_delayed_keypath_dynamic_member_works() {
}
}
}


// SR-11465 - Ambiguity in expression which matches both dynamic member lookup and declaration from constrained extension

@dynamicMemberLookup
struct SR_11465<RawValue> {
var rawValue: RawValue

subscript<Subject>(dynamicMember keyPath: KeyPath<RawValue, Subject>) -> Subject {
rawValue[keyPath: keyPath]
}
}

extension SR_11465: Hashable, Equatable where RawValue: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(self.rawValue)
}
}

func test_constrained_ext_vs_dynamic_member() {
// CHECK: function_ref @$s29keypath_dynamic_member_lookup8SR_11465VAASHRzlE9hashValueSivg
_ = SR_11465<Int>(rawValue: 1).hashValue // Ok, keep choice from constrained extension
}

0 comments on commit e0160a4

Please sign in to comment.