Skip to content

Commit f8bde21

Browse files
authored
Merge pull request #66035 from xedin/rdar-109245375
[Diagnostics] Skip overloaded locations where all solutions have the same type
2 parents 4590aa1 + f12e24e commit f8bde21

File tree

2 files changed

+79
-4
lines changed

2 files changed

+79
-4
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5313,12 +5313,18 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
53135313
/// provided set.
53145314
static unsigned countDistinctOverloads(ArrayRef<OverloadChoice> choices) {
53155315
llvm::SmallPtrSet<void *, 4> uniqueChoices;
5316-
unsigned result = 0;
53175316
for (auto choice : choices) {
5318-
if (uniqueChoices.insert(choice.getOpaqueChoiceSimple()).second)
5319-
++result;
5317+
uniqueChoices.insert(choice.getOpaqueChoiceSimple());
53205318
}
5321-
return result;
5319+
return uniqueChoices.size();
5320+
}
5321+
5322+
static Type getOverloadChoiceType(ConstraintLocator *overloadLoc,
5323+
const Solution &solution) {
5324+
auto selectedOverload = solution.overloadChoices.find(overloadLoc);
5325+
if (selectedOverload == solution.overloadChoices.end())
5326+
return Type();
5327+
return solution.simplifyType(selectedOverload->second.adjustedOpenedType);
53225328
}
53235329

53245330
/// Determine the name of the overload in a set of overload choices.
@@ -5400,6 +5406,25 @@ bool ConstraintSystem::diagnoseAmbiguity(ArrayRef<Solution> solutions) {
54005406
auto &overload = diff.overloads[i];
54015407
auto *locator = overload.locator;
54025408

5409+
// If there is only one overload difference, it's the best.
5410+
if (n == 1) {
5411+
bestOverload = i;
5412+
break;
5413+
}
5414+
5415+
// If there are multiple overload sets involved, let's pick the
5416+
// one that has choices with different types, because that is
5417+
// most likely the source of ambiguity.
5418+
{
5419+
auto overloadTy = getOverloadChoiceType(locator, solutions.front());
5420+
if (std::all_of(solutions.begin() + 1, solutions.end(),
5421+
[&](const Solution &solution) {
5422+
return overloadTy->isEqual(
5423+
getOverloadChoiceType(locator, solution));
5424+
}))
5425+
continue;
5426+
}
5427+
54035428
ASTNode anchor;
54045429

54055430
// Simplification of member locator would produce a base expression,
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %target-typecheck-verify-swift -swift-version 5 -disable-availability-checking
2+
3+
protocol View {
4+
}
5+
6+
extension View {
7+
func title<S>(_ title: S) -> some View where S : StringProtocol {
8+
EmptyView()
9+
}
10+
11+
func title(_ titleKey: LocalizedString) -> some View {
12+
EmptyView()
13+
}
14+
}
15+
16+
extension View {
17+
func background<T: ShapeStyle>(_: T) -> some View {
18+
EmptyView()
19+
}
20+
}
21+
22+
struct EmptyView : View {}
23+
24+
struct Text : View {
25+
init(_: String) {}
26+
}
27+
28+
protocol ShapeStyle {
29+
}
30+
31+
struct AnyShapeStyle : ShapeStyle {}
32+
struct AnyGradient : ShapeStyle {}
33+
34+
struct LocalizedString : ExpressibleByStringLiteral, ExpressibleByExtendedGraphemeClusterLiteral {
35+
init(extendedGraphemeClusterLiteral value: String) {}
36+
init(stringLiteral: String) {}
37+
}
38+
39+
func test() {
40+
func __findValue(_: String, fallback: LocalizedString) -> LocalizedString { fatalError() }
41+
func __findValue<T: ExpressibleByStringLiteral>(_: String, fallback: T) -> T { fatalError() }
42+
func __findValue<T: ExpressibleByExtendedGraphemeClusterLiteral>(_: String, fallback: T) -> T { fatalError() }
43+
44+
func ambiguitySource() -> AnyShapeStyle { fatalError() } // expected-note {{found this candidate}}
45+
func ambiguitySource() -> AnyGradient { fatalError() } // expected-note {{found this candidate}}
46+
47+
Text("Test")
48+
.title(__findValue("someKey", fallback: "<unknown>"))
49+
.background(ambiguitySource()) // expected-error {{ambiguous use of 'ambiguitySource()'}}
50+
}

0 commit comments

Comments
 (0)