Skip to content

Commit 23589ad

Browse files
committed
[CSOptimizer] Average score should reflect number of defaulted parameters
1 parent 6698136 commit 23589ad

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -441,14 +441,16 @@ static Constraint *determineBestChoicesInContext(
441441
}
442442

443443
double score = 0.0;
444+
unsigned numDefaulted = 0;
444445
for (unsigned paramIdx = 0, n = overloadType->getNumParams();
445446
paramIdx != n; ++paramIdx) {
446447
const auto &param = overloadType->getParams()[paramIdx];
447448

448449
auto argIndices = matchings->parameterBindings[paramIdx];
449450
switch (argIndices.size()) {
450451
case 0:
451-
// Current parameter is defaulted.
452+
// Current parameter is defaulted, mark and continue.
453+
++numDefaulted;
452454
continue;
453455

454456
case 1:
@@ -542,9 +544,14 @@ static Constraint *determineBestChoicesInContext(
542544
score += bestCandidateScore;
543545
}
544546

547+
// An overload whether all of the parameters are defaulted
548+
// that's called without arguments.
549+
if (numDefaulted == overloadType->getNumParams())
550+
return;
551+
545552
// Average the score to avoid disfavoring disjunctions with fewer
546553
// parameters.
547-
score /= overloadType->getNumParams();
554+
score /= (overloadType->getNumParams() - numDefaulted);
548555

549556
// If one of the result types matches exactly, that's a good
550557
// indication that overload choice should be favored.

test/Constraints/old_hack_related_ambiguities.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,25 @@ do {
3939
}
4040
}
4141

42+
// error: initializer for conditional binding must have Optional type, not 'S'
43+
do {
44+
struct S {
45+
let n: Int
46+
}
47+
48+
func f(_: String, _ p: Bool = false) -> S? {
49+
nil
50+
}
51+
52+
func f(_ x: String) -> S {
53+
fatalError()
54+
}
55+
56+
func g(_ x: String) -> Int? {
57+
guard let y = f(x) else {
58+
return nil
59+
}
60+
return y.n
61+
}
62+
}
63+

0 commit comments

Comments
 (0)