mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CSRanking] Always rank key path dynamic member choices lower than non-dynamic ones
This only comes into play when all other choices are coming from constrained extensions, because there is no way to determine upfront whether any are going to match it's better to be safe and add key path dynamic member choice to the set too. Resolves: [SR-11465](https://bugs.swift.org/browse/SR-11465) Resolves: rdar://problem/55314724
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user