Skip to content

Commit 4b01c8f

Browse files
committed
[ConstraintSystem] Adjust impact of implicit Double <-> CGFloat conversions
- Prefer CGFloat -> Double over the other way around to avoid ambiguities; - Every new conversion impacts the score by factor of number of previously applied conversions to make it possible to select solutions that require the least such conversions. - Prefer concrete overloads with Double <-> CGFloat conversion over generic ones.
1 parent 7fee597 commit 4b01c8f

File tree

7 files changed

+25
-16
lines changed

7 files changed

+25
-16
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -790,10 +790,6 @@ enum ScoreKind {
790790
SK_DisfavoredOverload,
791791
/// A member for an \c UnresolvedMemberExpr found via unwrapped optional base.
792792
SK_UnresolvedMemberViaOptional,
793-
/// An implicit conversion from a value of one type (lhs)
794-
/// to another type (rhs) via implicit initialization of
795-
/// `rhs` type which an argument of `lhs` value.
796-
SK_ImplicitValueConversion,
797793
/// An implicit force of an implicitly unwrapped optional value.
798794
SK_ForceUnchecked,
799795
/// A user-defined conversion.
@@ -814,8 +810,12 @@ enum ScoreKind {
814810
SK_ValueToPointerConversion,
815811
/// A closure/function conversion to an autoclosure parameter.
816812
SK_FunctionToAutoClosureConversion,
813+
/// An implicit conversion from a value of one type (lhs)
814+
/// to another type (rhs) via implicit initialization of
815+
/// `rhs` type which an argument of `lhs` value.
816+
SK_ImplicitValueConversion,
817817

818-
SK_LastScoreKind = SK_FunctionToAutoClosureConversion,
818+
SK_LastScoreKind = SK_ImplicitValueConversion,
819819
};
820820

821821
/// The number of score kinds.

lib/Sema/CSSimplify.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10527,7 +10527,14 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1052710527

1052810528
case ConversionRestrictionKind::DoubleToCGFloat:
1052910529
case ConversionRestrictionKind::CGFloatToDouble: {
10530-
increaseScore(SK_ImplicitValueConversion);
10530+
// Prefer CGFloat -> Double over other way araund.
10531+
auto defaultImpact =
10532+
restriction == ConversionRestrictionKind::CGFloatToDouble ? 1 : 2;
10533+
10534+
auto numConversions = CurrentScore.Data[SK_ImplicitValueConversion];
10535+
increaseScore(SK_ImplicitValueConversion,
10536+
defaultImpact * (numConversions + 1));
10537+
1053110538
if (worseThanBestSolution())
1053210539
return SolutionKind::Error;
1053310540

lib/Sema/CSStep.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,6 @@ bool DisjunctionStep::shouldStopAt(const DisjunctionChoice &choice) const {
710710
auto *lastChoice = LastSolvedChoice->first;
711711
auto delta = LastSolvedChoice->second - getCurrentScore();
712712
bool hasUnavailableOverloads = delta.Data[SK_Unavailable] > 0;
713-
bool hasImplicitConversions = delta.Data[SK_ImplicitValueConversion] > 0;
714713
bool hasFixes = delta.Data[SK_Fix] > 0;
715714
bool hasAsyncMismatch = delta.Data[SK_AsyncInSyncMismatch] > 0;
716715
auto isBeginningOfPartition = choice.isBeginningOfPartition();
@@ -720,9 +719,7 @@ bool DisjunctionStep::shouldStopAt(const DisjunctionChoice &choice) const {
720719
// 1. selecting unavailable overloads
721720
// 2. result in fixes being applied to reach a solution
722721
// 3. selecting an overload that results in an async/sync mismatch
723-
// 4. implicit value conversions
724722
return !hasUnavailableOverloads && !hasFixes && !hasAsyncMismatch &&
725-
!hasImplicitConversions &&
726723
(isBeginningOfPartition ||
727724
shortCircuitDisjunctionAt(choice, lastChoice));
728725
}

lib/Sema/CSStep.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -691,11 +691,10 @@ class DisjunctionStep final : public BindingStep<DisjunctionChoiceProducer> {
691691
// non-generic score indicates that there were no forced
692692
// unwrappings of optional(s), no unavailable overload
693693
// choices present in the solution, no fixes required,
694-
// and there are no non-trivial function or value conversions.
694+
// and there are no non-trivial function conversions.
695695
auto &score = BestNonGenericScore->Data;
696696
return (score[SK_ForceUnchecked] == 0 && score[SK_Unavailable] == 0 &&
697-
score[SK_Fix] == 0 && score[SK_FunctionConversion] == 0 &&
698-
score[SK_ImplicitValueConversion] == 0);
697+
score[SK_Fix] == 0 && score[SK_FunctionConversion] == 0);
699698
}
700699

701700
/// Attempt to apply given disjunction choice to constraint system.

stdlib/public/Darwin/CoreGraphics/CGFloat.swift.gyb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,11 @@ extension CGFloat {
470470
lhs /= rhs
471471
return lhs
472472
}
473+
474+
@_transparent
475+
public static prefix func -(x: CGFloat) -> CGFloat {
476+
return 0 - x
477+
}
473478
}
474479

475480
//===----------------------------------------------------------------------===//
@@ -596,7 +601,8 @@ public func remquo(_ x: CGFloat, _ y: CGFloat) -> (CGFloat, Int) {
596601
"use CGFloat(nan: CGFloat.RawSignificand) instead.")
597602
@_transparent
598603
public func nan(_ tag: String) -> CGFloat {
599-
return CGFloat(nan(tag) as CGFloat.NativeType)
604+
let NaN: Float = nan(tag)
605+
return CGFloat(CGFloat.NativeType(NaN))
600606
}
601607

602608
@_transparent

test/Misc/misc_diagnostics.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,14 @@ func test_implicit_cgfloat_conversion() {
186186
test_to(f) // expected-error {{cannot convert value of type 'Float' to expected argument type 'CGFloat'}}
187187
test_to(d + d) // Ok (Double -> CGFloat for both arguments)
188188
test_to(d + cgf) // Ok
189-
test_to(d + cgf - d) // expected-error {{ambiguous use of operator '+'}} (Both Double and CGFloat are equaly viable here)
189+
test_to(d + cgf - d) // Ok (prefer CGFloat -> Double for `cgf`), it's a better solution than trying to convert `d`s to `CGFloat`
190190
test_to(d + cgf - cgf) // Ok (only one choice here to conver `d` to CGFloat)
191191

192192
test_from(cgf) // Ok (CGFloat -> Double)
193193
test_from(f) // expected-error {{cannot convert value of type 'Float' to expected argument type 'Double'}}
194194
test_from(cgf + cgf) // Ok (CGFloat -> Double for both arguments)
195195
test_from(d + cgf) // Ok
196-
test_from(cgf + d - cgf) // expected-error {{ambiguous use of operator '+'}} (Both Double and CGFloat are equaly viable here)
196+
test_from(cgf + d - cgf) // (prefer Double -> CGFloat for `d`), it's a better solution than trying to convert `cgf`s to `Double`
197197
test_from(cgf + d - d) // Ok (only one choice here to conver `cgf` to Double)
198198

199199
func test_returns_double(_: CGFloat) -> Double {

validation-test/Sema/type_checker_perf/slow/rdar46541800.swift renamed to validation-test/Sema/type_checker_perf/fast/rdar46541800.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class SomeView {
1616
let displayScale: CGFloat = CGFloat()
1717
let _ = (descriptionTextViewFrame.height
1818
+ (-descriptionTextView.lastBaselineOffsetFromBottom - textInset.bottom + descriptionLabelProperties.lastBaselineOffsetFromBottom)
19-
+ (-descriptionTextView.firstBaselineOffsetFromTop - textInset.top + descriptionTextBaselineOffset).ceilingValue(scale: displayScale) // expected-error {{reasonable time}}
19+
+ (-descriptionTextView.firstBaselineOffsetFromTop - textInset.top + descriptionTextBaselineOffset).ceilingValue(scale: displayScale)
2020
)
2121
}
2222

0 commit comments

Comments
 (0)