@@ -5091,18 +5091,36 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
5091
5091
auto anchor = locator.getLocatorParts (path);
5092
5092
5093
5093
// Try implicit CGFloat conversion only if:
5094
- // - This is not an explicit call to a CGFloat initializer;
5094
+ // - This is not:
5095
+ // - an explicit call to a CGFloat initializer;
5096
+ // - an explicit coercion;
5097
+ // - a runtime type check (via `is` expression);
5098
+ // - a checked or conditional cast;
5095
5099
// - This is a first type such conversion is attempted for
5096
5100
// for a given path (AST element).
5097
5101
5098
- bool isCGFloatInit = false ;
5099
- if (auto *call = getAsExpr<CallExpr>(anchor)) {
5100
- if (auto *typeExpr = dyn_cast<TypeExpr>(call->getFn ())) {
5101
- isCGFloatInit = getInstanceType (typeExpr)->isCGFloatType ();
5102
+ auto isCGFloatInit = [&](ASTNode location) {
5103
+ if (auto *call = getAsExpr<CallExpr>(location)) {
5104
+ if (auto *typeExpr = dyn_cast<TypeExpr>(call->getFn ())) {
5105
+ return getInstanceType (typeExpr)->isCGFloatType ();
5106
+ }
5102
5107
}
5103
- }
5108
+ return false ;
5109
+ };
5110
+
5111
+ auto isCoercionOrCast = [](ASTNode anchor,
5112
+ ArrayRef<LocatorPathElt> path) {
5113
+ // e.g. contextual conversion from coercion/cast
5114
+ // to some other type.
5115
+ if (!path.empty ())
5116
+ return false ;
5117
+
5118
+ return isExpr<CoerceExpr>(anchor) || isExpr<IsExpr>(anchor) ||
5119
+ isExpr<ConditionalCheckedCastExpr>(anchor) ||
5120
+ isExpr<ForcedCheckedCastExpr>(anchor);
5121
+ };
5104
5122
5105
- if (!isCGFloatInit &&
5123
+ if (!isCGFloatInit (anchor) && ! isCoercionOrCast (anchor, path) &&
5106
5124
llvm::none_of (path, [&](const LocatorPathElt &rawElt) {
5107
5125
if (auto elt =
5108
5126
rawElt.getAs <LocatorPathElt::ImplicitConversion>()) {
0 commit comments