Skip to content

Commit cd3ec8c

Browse files
committed
[ConstraintSystem] Allow attempting generic unary operators in presence of Double<->CGFloat conversion
Not all of the unary operators have `CGFloat` overloads, so in order to preserve previous behavior (and overall best solution) with implicit Double<->CGFloat conversion we need to allow attempting generic operators for such cases. ```swift let _: CGFloat = -.pi / 2 ``` `-` doesn't have `CGFloat` overload (which might be an oversight), so in order to preserve type-checking behavior solver can't be allowed to pick `-(Double) -> Double` based on overload of `/`, the best possible solution would be with `/` as `(CGFloat, CGFloat) -> CGFloat` and `-` on a `FloatingPoint` protocol.
1 parent cf8005b commit cd3ec8c

File tree

3 files changed

+23
-3
lines changed

3 files changed

+23
-3
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5349,11 +5349,12 @@ class DisjunctionChoice {
53495349

53505350
bool isBeginningOfPartition() const { return IsBeginningOfPartition; }
53515351

5352-
// FIXME: Both of the accessors below are required to support
5352+
// FIXME: All three of the accessors below are required to support
53535353
// performance optimization hacks in constraint solver.
53545354

53555355
bool isGenericOperator() const;
53565356
bool isSymmetricOperator() const;
5357+
bool isUnaryOperator() const;
53575358

53585359
void print(llvm::raw_ostream &Out, SourceManager *SM) const {
53595360
Out << "disjunction choice ";

lib/Sema/CSSolver.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2167,6 +2167,15 @@ bool DisjunctionChoice::isSymmetricOperator() const {
21672167
return firstType->isEqual(secondType);
21682168
}
21692169

2170+
bool DisjunctionChoice::isUnaryOperator() const {
2171+
auto *decl = getOperatorDecl(Choice);
2172+
if (!decl)
2173+
return false;
2174+
2175+
auto func = cast<FuncDecl>(decl);
2176+
return func->getParameters()->size() == 1;
2177+
}
2178+
21702179
void DisjunctionChoice::propagateConversionInfo(ConstraintSystem &cs) const {
21712180
assert(ExplicitConversion);
21722181

lib/Sema/CSStep.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,8 +696,18 @@ bool DisjunctionStep::shouldSkip(const DisjunctionChoice &choice) const {
696696
// already have a solution involving non-generic operators,
697697
// but continue looking for a better non-generic operator
698698
// solution.
699-
if (shouldSkipGenericOperators() && choice.isGenericOperator()) {
700-
return skip("generic");
699+
if (BestNonGenericScore && choice.isGenericOperator()) {
700+
auto &score = BestNonGenericScore->Data;
701+
702+
// Not all of the unary operators have `CGFloat` overloads,
703+
// so in order to preserve previous behavior (and overall
704+
// best solution) with implicit Double<->CGFloat conversion
705+
// we need to allow attempting generic operators for such cases.
706+
if (score[SK_ImplicitValueConversion] > 0 && choice.isUnaryOperator())
707+
return false;
708+
709+
if (shouldSkipGenericOperators())
710+
return skip("generic");
701711
}
702712

703713
return false;

0 commit comments

Comments
 (0)