Skip to content

Commit 0737542

Browse files
committed
[CSOptimizer] Favor choices that don't require application
When disjunction is not applied, don't only bump its score but also favor all of the choices that don't require application because selection algorithm uses that for comparison. This is important for situation when property is overload with a method i.e. `Array.count`.
1 parent 55189ba commit 0737542

File tree

2 files changed

+25
-2
lines changed

2 files changed

+25
-2
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ static bool isFloatType(Type type) {
6161
return type->isFloat() || type->isDouble() || type->isFloat80();
6262
}
6363

64+
static bool isUnboundArrayType(Type type) {
65+
if (auto *UGT = type->getAs<UnboundGenericType>())
66+
return UGT->getDecl() == type->getASTContext().getArrayDecl();
67+
return false;
68+
}
69+
6470
static bool isSupportedOperator(Constraint *disjunction) {
6571
if (!isOperatorDisjunction(disjunction))
6672
return false;
@@ -298,9 +304,19 @@ static void determineBestChoicesInContext(
298304
case ExprKind::Binary:
299305
case ExprKind::PrefixUnary:
300306
case ExprKind::PostfixUnary:
301-
case ExprKind::UnresolvedDot:
302-
recordResult(disjunction, {/*score=*/1.0});
307+
case ExprKind::UnresolvedDot: {
308+
llvm::SmallVector<Constraint *, 2> favoredChoices;
309+
// Favor choices that don't require application.
310+
llvm::copy_if(
311+
disjunction->getNestedConstraints(),
312+
std::back_inserter(favoredChoices), [](Constraint *choice) {
313+
auto *decl = getOverloadChoiceDecl(choice);
314+
return decl &&
315+
!decl->getInterfaceType()->is<AnyFunctionType>();
316+
});
317+
recordResult(disjunction, {/*score=*/1.0, favoredChoices});
303318
continue;
319+
}
304320

305321
default:
306322
break;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-typecheck-verify-swift -solver-expression-time-threshold=5
2+
// REQUIRES: tools-release,no_asan
3+
4+
func f(n: Int, a: [Int]) {
5+
let _ = [(0 ..< n + a.count).map { Int8($0) }] +
6+
[(0 ..< n + a.count).map { Int8($0) }.reversed()] // Ok
7+
}

0 commit comments

Comments
 (0)