mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CSOptimizer] Rank results of operators regardless of whether anything is known about parameters
When operators are chained it's possible that we don't know anything about parameter(s) but result is known from the context, we should use that information.
This commit is contained in:
@@ -57,6 +57,15 @@ static bool isSupportedOperator(Constraint *disjunction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isStandardComparisonOperator(ValueDecl *decl) {
|
||||
return decl->isOperator() &&
|
||||
decl->getBaseIdentifier().isStandardComparisonOperator();
|
||||
}
|
||||
|
||||
static bool isArithmeticOperator(ValueDecl *decl) {
|
||||
return decl->isOperator() && decl->getBaseIdentifier().isArithmeticOperator();
|
||||
}
|
||||
|
||||
static bool isSupportedDisjunction(Constraint *disjunction) {
|
||||
auto choices = disjunction->getNestedConstraints();
|
||||
|
||||
@@ -561,9 +570,7 @@ static Constraint *determineBestChoicesInContext(
|
||||
// ones that all have the same result type), regular
|
||||
// functions/methods and especially initializers could end up
|
||||
// with a lot of favored overloads because on the result type alone.
|
||||
if (score > 0 ||
|
||||
(decl->isOperator() &&
|
||||
!decl->getBaseIdentifier().isStandardComparisonOperator())) {
|
||||
if (decl->isOperator() && !isStandardComparisonOperator(decl)) {
|
||||
if (llvm::any_of(resultTypes, [&](const Type candidateResultTy) {
|
||||
return scoreCandidateMatch(genericSig,
|
||||
overloadType->getResult(),
|
||||
@@ -575,15 +582,14 @@ static Constraint *determineBestChoicesInContext(
|
||||
}
|
||||
|
||||
if (score > 0) {
|
||||
if (decl->isOperator() &&
|
||||
decl->getBaseIdentifier().isArithmeticOperator() &&
|
||||
// Nudge the score slightly to prefer concrete homogeneous
|
||||
// arithmetic operators.
|
||||
//
|
||||
// This is an opportunistic optimization based on the operator
|
||||
// use patterns where homogeneous operators are the most
|
||||
// heavily used ones.
|
||||
if (isArithmeticOperator(decl) &&
|
||||
overloadType->getNumParams() == 2) {
|
||||
// Nudge the score slightly to prefer concrete homogeneous
|
||||
// operators.
|
||||
//
|
||||
// This is an opportunistic optimization based on the operator
|
||||
// use patterns where homogeneous operators are the most
|
||||
// heavily used ones.
|
||||
auto resultTy = overloadType->getResult();
|
||||
if (!resultTy->hasTypeParameter() &&
|
||||
llvm::all_of(overloadType->getParams(),
|
||||
|
||||
@@ -5,5 +5,4 @@
|
||||
func test(bytes: Int, length: UInt32) {
|
||||
// left-hand side of `>=` is `Int` and right-hand side is a chain of `UInt32` inferred from `length`
|
||||
_ = bytes >= 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + length
|
||||
// expected-error@-1 {{reasonable time}}
|
||||
}
|
||||
Reference in New Issue
Block a user