Skip to content

Commit 8c60176

Browse files
committed
[ConstraintSystem] Limit new implicit conversion to only Double <-> CGFloat
1 parent b7fcae4 commit 8c60176

File tree

8 files changed

+53
-27
lines changed

8 files changed

+53
-27
lines changed

include/swift/Sema/Constraint.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,12 @@ enum class ConversionRestrictionKind {
258258
/// Implicit conversion from an Objective-C class type to its
259259
/// toll-free-bridged CF type.
260260
ObjCTollFreeBridgeToCF,
261-
/// Implicit conversion from a CGFloat to another compatible type via
261+
/// Implicit conversion from a value of Double to a value of CGFloat type via
262262
/// an implicit CGFloat initializer call.
263-
TypeToCGFloat,
264-
/// Implicit conversion from a compatible value to a CGFloat via
265-
/// an implicit call to an initializer passing CGFloat value.
266-
CGFloatToType,
263+
DoubleToCGFloat,
264+
/// Implicit conversion from a value of CGFloat type to a value of Double type
265+
/// via an implicit call to an initializer passing CGFloat value.
266+
CGFloatToDouble,
267267
};
268268

269269
/// Specifies whether a given conversion requires the creation of a temporary

lib/Sema/CSApply.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6690,8 +6690,8 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
66906690
ForeignObjectConversionExpr(result, toType));
66916691
}
66926692

6693-
case ConversionRestrictionKind::CGFloatToType:
6694-
case ConversionRestrictionKind::TypeToCGFloat: {
6693+
case ConversionRestrictionKind::CGFloatToDouble:
6694+
case ConversionRestrictionKind::DoubleToCGFloat: {
66956695
auto *fnExpr = TypeExpr::createImplicit(toType, ctx);
66966696
cs.cacheExprTypes(fnExpr);
66976697

lib/Sema/CSDiagnostics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6406,8 +6406,8 @@ void NonEphemeralConversionFailure::emitSuggestionNotes() const {
64066406
case ConversionRestrictionKind::HashableToAnyHashable:
64076407
case ConversionRestrictionKind::CFTollFreeBridgeToObjC:
64086408
case ConversionRestrictionKind::ObjCTollFreeBridgeToCF:
6409-
case ConversionRestrictionKind::CGFloatToType:
6410-
case ConversionRestrictionKind::TypeToCGFloat:
6409+
case ConversionRestrictionKind::CGFloatToDouble:
6410+
case ConversionRestrictionKind::DoubleToCGFloat:
64116411
llvm_unreachable("Expected an ephemeral conversion!");
64126412
}
64136413
}

lib/Sema/CSSimplify.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5089,9 +5089,14 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
50895089
}
50905090
}
50915091

5092+
auto isDoubleType = [&](NominalType *NTD) {
5093+
return NTD->getDecl() == getASTContext().getDoubleDecl();
5094+
};
5095+
50925096
if (kind >= ConstraintKind::Subtype &&
50935097
nominal1->getDecl() != nominal2->getDecl() &&
5094-
(desugar1->isCGFloatType() || desugar2->isCGFloatType())) {
5098+
((nominal1->isCGFloatType() || nominal2->isCGFloatType()) &&
5099+
(isDoubleType(nominal1) || isDoubleType(nominal2)))) {
50955100
SmallVector<LocatorPathElt, 4> path;
50965101
auto anchor = locator.getLocatorParts(path);
50975102

@@ -5112,15 +5117,15 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
51125117
if (auto elt =
51135118
rawElt.getAs<LocatorPathElt::ImplicitConversion>()) {
51145119
auto convKind = elt->getConversionKind();
5115-
return convKind == ConversionRestrictionKind::TypeToCGFloat ||
5116-
convKind == ConversionRestrictionKind::CGFloatToType;
5120+
return convKind == ConversionRestrictionKind::DoubleToCGFloat ||
5121+
convKind == ConversionRestrictionKind::CGFloatToDouble;
51175122
}
51185123
return false;
51195124
})) {
51205125
conversionsOrFixes.push_back(
51215126
desugar1->isCGFloatType()
5122-
? ConversionRestrictionKind::CGFloatToType
5123-
: ConversionRestrictionKind::TypeToCGFloat);
5127+
? ConversionRestrictionKind::CGFloatToDouble
5128+
: ConversionRestrictionKind::DoubleToCGFloat);
51245129
}
51255130
}
51265131

@@ -10523,8 +10528,8 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1052310528
ConstraintKind::Subtype, subflags, locator);
1052410529
}
1052510530

10526-
case ConversionRestrictionKind::TypeToCGFloat:
10527-
case ConversionRestrictionKind::CGFloatToType: {
10531+
case ConversionRestrictionKind::DoubleToCGFloat:
10532+
case ConversionRestrictionKind::CGFloatToDouble: {
1052810533
increaseScore(SK_ImplicitValueConversion);
1052910534
if (worseThanBestSolution())
1053010535
return SolutionKind::Error;

lib/Sema/Constraint.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -548,10 +548,10 @@ StringRef swift::constraints::getName(ConversionRestrictionKind kind) {
548548
return "[cf-toll-free-bridge-to-objc]";
549549
case ConversionRestrictionKind::ObjCTollFreeBridgeToCF:
550550
return "[objc-toll-free-bridge-to-cf]";
551-
case ConversionRestrictionKind::CGFloatToType:
552-
return "[CGFloat-to-type]";
553-
case ConversionRestrictionKind::TypeToCGFloat:
554-
return "[type-to-CGFloat]";
551+
case ConversionRestrictionKind::CGFloatToDouble:
552+
return "[CGFloat-to-Double]";
553+
case ConversionRestrictionKind::DoubleToCGFloat:
554+
return "[Double-to-CGFloat]";
555555
}
556556
llvm_unreachable("bad conversion restriction kind");
557557
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4488,8 +4488,8 @@ ConstraintSystem::getArgumentInfo(ConstraintLocator *locator) {
44884488
.castTo<LocatorPathElt::ImplicitConversion>()
44894489
.getConversionKind();
44904490

4491-
if (conversion == ConversionRestrictionKind::TypeToCGFloat ||
4492-
conversion == ConversionRestrictionKind::CGFloatToType) {
4491+
if (conversion == ConversionRestrictionKind::DoubleToCGFloat ||
4492+
conversion == ConversionRestrictionKind::CGFloatToDouble) {
44934493
// TODO: This is not very efficient, long term we should just
44944494
// save a single `ArgumentInfo` and use it for all of
44954495
// the locations where conversion is needed.
@@ -4902,8 +4902,8 @@ ConstraintSystem::isConversionEphemeral(ConversionRestrictionKind conversion,
49024902
case ConversionRestrictionKind::HashableToAnyHashable:
49034903
case ConversionRestrictionKind::CFTollFreeBridgeToObjC:
49044904
case ConversionRestrictionKind::ObjCTollFreeBridgeToCF:
4905-
case ConversionRestrictionKind::CGFloatToType:
4906-
case ConversionRestrictionKind::TypeToCGFloat:
4905+
case ConversionRestrictionKind::CGFloatToDouble:
4906+
case ConversionRestrictionKind::DoubleToCGFloat:
49074907
// @_nonEphemeral has no effect on these conversions, so treat them as all
49084908
// being non-ephemeral in order to allow their passing to an @_nonEphemeral
49094909
// parameter.

test/Constraints/bridging.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ let d2: Double = 3.14159
208208
inferDouble2 = d2
209209

210210
// rdar://problem/18269449
211-
var i1: Int = 1.5 * 3.5 // Ok (Double -> CGFloat for each argument, CGFloat -> Int for the result)
211+
var i1: Int = 1.5 * 3.5 // expected-error {{cannot convert value of type 'Double' to specified type 'Int'}}
212212

213213
// rdar://problem/18330319
214214
func rdar18330319(_ s: String, d: [String : AnyObject]) {

test/Misc/misc_diagnostics.swift

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ var pi = 3.14159265358979
1919
var d: CGFloat = 2.0
2020
var dpi:CGFloat = d*pi // Ok (implicit conversion Float -> CGFloat)
2121

22-
let ff: CGFloat = floorf(20.0) // Ok (implicit conversion Float -> CGFloat)
22+
let ff: CGFloat = floorf(20.0) // expected-error{{cannot convert value of type 'Float' to specified type 'CGFloat'}}
23+
let _: CGFloat = floor(20.0) // Ok (Double -> CGFloat) conversion
2324

2425
let total = 15.0
2526
let count = 7
@@ -34,7 +35,7 @@ var b: Int = [1, 2, 3] // expected-error{{cannot convert value of type '[Int]' t
3435
var f1: Float = 2.0
3536
var f2: Float = 3.0
3637

37-
var dd: Double = f1 - f2 // Ok (implicit conversion Float -> CGFloat for each argument and CGFloat -> Double for the result)
38+
var dd: Double = f1 - f2 // expected-error{{cannot convert value of type 'Float' to specified type 'Double'}}
3839

3940
func f() -> Bool {
4041
return 1 + 1 // expected-error{{type 'Int' cannot be used as a boolean; test for '!= 0' instead}}
@@ -172,3 +173,23 @@ func tuple_splat2(_ q : (a : Int, b : Int)) {
172173
func is_foreign(a: AnyObject) -> Bool {
173174
return a is CGColor // expected-warning {{'is' test is always true because 'CGColor' is a Core Foundation type}}
174175
}
176+
177+
func test_implicit_cgfloat_conversion() {
178+
func test_to(_: CGFloat) {}
179+
func test_from(_: Double) {}
180+
181+
let d: Double = 0.0
182+
let f: Float = 0.0
183+
let cgf: CGFloat = 0.0
184+
185+
test_to(d) // Ok (Double -> CGFloat
186+
test_to(f) // error
187+
188+
test_from(cgf) // Ok (CGFloat -> Double)
189+
test_from(f) // error
190+
191+
let _: CGFloat = d // Ok
192+
let _: CGFloat = f // error
193+
let _: Double = cgf // Ok
194+
let _: Float = cgf // error
195+
}

0 commit comments

Comments
 (0)