Skip to content

Commit 288a776

Browse files
committed
[CSRanking] Detect cases where overload choices are incomparable
If constraint system is underconstrained e.g. because there are editor placeholders, it's possible to end up with multiple solutions where each ambiguous declaration is going to have its own overload kind: ```swift func foo(_: Int) -> [Int] { ... } func foo(_: Double) -> (result: String, count: Int) { ... } _ = foo(<#arg#>).count ``` In this case solver would produce 2 solutions: one where `count` is a property reference on `[Int]` and another one is tuple access for a `count:` element. Resolves: rdar://problem/49712598
1 parent 0f0a908 commit 288a776

File tree

2 files changed

+22
-0
lines changed

2 files changed

+22
-0
lines changed

lib/Sema/CSRanking.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,21 @@ SolutionCompareResult ConstraintSystem::compareSolutions(
799799
if (sameOverloadChoice(choice1, choice2))
800800
continue;
801801

802+
// If constraint system is underconstrained e.g. because there are
803+
// editor placeholders, it's possible to end up with multiple solutions
804+
// where each ambiguous declaration is going to have its own overload kind:
805+
//
806+
// func foo(_: Int) -> [Int] { ... }
807+
// func foo(_: Double) -> (result: String, count: Int) { ... }
808+
//
809+
// _ = foo(<#arg#>).count
810+
//
811+
// In this case solver would produce 2 solutions: one where `count`
812+
// is a property reference on `[Int]` and another one is tuple access
813+
// for a `count:` element.
814+
if (choice1.isDecl() != choice2.isDecl())
815+
return SolutionCompareResult::Incomparable;
816+
802817
auto decl1 = choice1.getDecl();
803818
auto dc1 = decl1->getDeclContext();
804819
auto decl2 = choice2.getDecl();

test/Sema/editor_placeholders.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,10 @@ f(<#T##String#>) // expected-error{{editor placeholder in source file}} expected
2929
for x in <#T#> { // expected-error{{editor placeholder in source file}} expected-error{{for-in loop requires '()' to conform to 'Sequence'}}
3030

3131
}
32+
33+
// rdar://problem/49712598 - crash while trying to rank solutions with different kinds of overloads
34+
func test_ambiguity_with_placeholders(pairs: [(rank: Int, count: Int)]) -> Bool {
35+
return pairs[<#^ARG^#>].count == 2
36+
// expected-error@-1 {{editor placeholder in source file}}
37+
// expected-error@-2 {{ambiguous use of 'subscript(_:)'}}
38+
}

0 commit comments

Comments
 (0)