Skip to content

Commit 56d9c47

Browse files
committed
Sema: Prefer class properties to protocol properties when ranking overloads
This was the old behavior in Swift 4.1, but it broke after some changes to redeclaration checking and shadowing. Fixes <rdar://problem/42201583>.
1 parent f2d5f97 commit 56d9c47

File tree

2 files changed

+40
-0
lines changed

2 files changed

+40
-0
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,26 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
939939
}
940940
}
941941

942+
// If both are properties and one is in a protocol, prefer the one not in
943+
// a protocol.
944+
//
945+
// This is a Swift 4.1 compatibility hack. Changes elsewhere in the compiler
946+
// made this case ambiguous. Perhaps it was never meant to be unambiguous in
947+
// the first place, because it only seemed to work for properties, and not
948+
// methods, so I'm going to keep this intentionally narrow.
949+
if (isa<VarDecl>(decl1) && isa<VarDecl>(decl2)) {
950+
auto *nominal1 = dc1->getAsNominalTypeOrNominalTypeExtensionContext();
951+
auto *nominal2 = dc2->getAsNominalTypeOrNominalTypeExtensionContext();
952+
953+
if (nominal1 && nominal2 && nominal1 != nominal2) {
954+
if (isa<ProtocolDecl>(nominal1))
955+
score2 += weight;
956+
957+
if (isa<ProtocolDecl>(nominal2))
958+
score1 += weight;
959+
}
960+
}
961+
942962
// If we haven't found a refinement, record whether one overload is in
943963
// any way more constrained than another. We'll only utilize this
944964
// information in the case of a potential ambiguity.

test/Constraints/ranking.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,23 @@ func testDerived(b: B) {
155155
f0(f1(b))
156156
// CHECK: end sil function '$S7ranking11testDerived1byAA1BC_tF'
157157
}
158+
159+
protocol X {
160+
var z: Int { get }
161+
}
162+
163+
class Y {
164+
var z: Int = 0
165+
}
166+
167+
// CHECK-LABEL: sil hidden @$S7ranking32testGenericPropertyProtocolClassyyxAA1YCRbzAA1XRzlF
168+
func testGenericPropertyProtocolClass<T : X & Y>(_ t: T) {
169+
// CHECK: class_method {{%.*}} : $Y, #Y.z!getter.1
170+
_ = t.z
171+
}
172+
173+
// CHECK-LABEL: sil hidden @$S7ranking36testExistentialPropertyProtocolClassyyAA1X_AA1YCXcF
174+
func testExistentialPropertyProtocolClass(_ t: X & Y) {
175+
// CHECK: class_method {{%.*}} : $Y, #Y.z!getter.1
176+
_ = t.z
177+
}

0 commit comments

Comments
 (0)