@@ -4162,7 +4162,7 @@ namespace {
4162
4162
4163
4163
// SIL-generation magically turns this into a Bool; make sure it can.
4164
4164
if (!ctx.getBoolBuiltinInitDecl()) {
4165
- ctx.Diags.diagnose(expr->getLoc(), diag::broken_bool );
4165
+ ctx.Diags.diagnose(expr->getLoc(), diag::broken_stdlib_type, "Bool" );
4166
4166
// Continue anyway.
4167
4167
}
4168
4168
@@ -4200,7 +4200,7 @@ namespace {
4200
4200
auto boolDecl = ctx.getBoolDecl();
4201
4201
4202
4202
if (!boolDecl) {
4203
- ctx.Diags.diagnose(SourceLoc(), diag::broken_bool );
4203
+ ctx.Diags.diagnose(SourceLoc(), diag::broken_stdlib_type, "Bool" );
4204
4204
}
4205
4205
4206
4206
cs.setType(isSomeExpr, boolDecl ? ctx.getBoolType() : Type());
@@ -5868,6 +5868,9 @@ static unsigned getOptionalEvaluationDepth(Expr *expr, Expr *target) {
5868
5868
depth += getOptionalEvaluationDepth(open->getSubExpr(),
5869
5869
open->getOpaqueValue());
5870
5870
expr = open->getExistentialValue();
5871
+ } else if (auto call = dyn_cast<CallExpr>(expr)) {
5872
+ // CGFloat <-> Double conversions lower to constructor calls.
5873
+ expr = call->getArgs()->getExpr(0);
5871
5874
5872
5875
// Otherwise, look through implicit conversions.
5873
5876
} else {
@@ -7262,77 +7265,46 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
7262
7265
7263
7266
case ConversionRestrictionKind::CGFloatToDouble:
7264
7267
case ConversionRestrictionKind::DoubleToCGFloat: {
7265
- auto conversionKind = knownRestriction->second;
7266
-
7267
- auto shouldUseCoercedExpr = [&]() {
7268
- // If conversion wraps the whole body of a single-expression closure,
7269
- // let's use the passed-in expression since the closure itself doesn't
7270
- // get updated until coercion is done.
7271
- if (locator.endsWith<LocatorPathElt::ClosureBody>())
7272
- return true;
7273
-
7274
- // Contextual type locator always uses the original version of
7275
- // expression (before any coercions have been applied) because
7276
- // otherwise it wouldn't be possible to find the overload choice.
7277
- if (locator.endsWith<LocatorPathElt::ContextualType>())
7278
- return true;
7279
-
7280
- // In all other cases use the expression associated with locator.
7281
- return false;
7282
- };
7283
-
7284
- auto *argExpr =
7285
- shouldUseCoercedExpr() ? expr : locator.trySimplifyToExpr();
7286
- assert(argExpr);
7287
-
7288
- // Source requires implicit conversion to match destination
7289
- // type but the conversion itself is recorded on assignment.
7290
- if (auto *assignment = dyn_cast<AssignExpr>(argExpr))
7291
- argExpr = assignment->getSrc();
7292
-
7293
- // Load the value for conversion.
7294
- argExpr = cs.coerceToRValue(argExpr);
7295
-
7296
- auto *argList = ArgumentList::forImplicitUnlabeled(ctx, {argExpr});
7297
- auto *implicitInit = CallExpr::createImplicit(
7298
- ctx, TypeExpr::createImplicit(toType, ctx), argList);
7299
-
7300
- cs.cacheExprTypes(implicitInit->getFn());
7301
- cs.setType(argExpr, fromType);
7302
-
7303
- auto *callLocator = cs.getConstraintLocator(
7304
- implicitInit, LocatorPathElt::ImplicitConversion(conversionKind));
7305
-
7306
- // HACK: Temporarily push the call expr onto the expr stack to make sure
7307
- // we don't try to prematurely close an existential when applying the
7308
- // curried member ref. This can be removed once existential opening is
7309
- // refactored not to rely on the shape of the AST prior to rewriting.
7310
- ExprStack.push_back(implicitInit);
7311
- SWIFT_DEFER { ExprStack.pop_back(); };
7312
-
7313
- // We need to take information recorded for all conversions of this
7314
- // kind and move it to a specific location where restriction is applied.
7315
- {
7316
- auto *memberLoc = solution.getConstraintLocator(
7317
- callLocator, {ConstraintLocator::ApplyFunction,
7318
- ConstraintLocator::ConstructorMember});
7319
-
7320
- ConstraintLocator *baseLoc =
7321
- cs.getImplicitValueConversionLocator(locator, conversionKind);
7268
+ DeclName name(ctx, DeclBaseName::createConstructor(), Identifier());
7269
+
7270
+ ConstructorDecl *decl = nullptr;
7271
+ SmallVector<ValueDecl *, 2> candidates;
7272
+ dc->lookupQualified(toType->getAnyNominal(),
7273
+ DeclNameRef(name), SourceLoc(),
7274
+ NL_QualifiedDefault, candidates);
7275
+ for (auto *candidate : candidates) {
7276
+ auto *ctor = cast<ConstructorDecl>(candidate);
7277
+ auto fnType = ctor->getMethodInterfaceType()->castTo<FunctionType>();
7278
+ if (fnType->getNumParams() == 1 &&
7279
+ fnType->getParams()[0].getPlainType()->isEqual(fromType) &&
7280
+ fnType->getResult()->isEqual(toType)) {
7281
+ decl = ctor;
7282
+ break;
7283
+ }
7284
+ }
7322
7285
7323
- auto overload =
7324
- solution.getOverloadChoice(solution.getConstraintLocator(
7325
- baseLoc, {ConstraintLocator::ApplyFunction,
7326
- ConstraintLocator::ConstructorMember}));
7286
+ if (decl == nullptr) {
7287
+ ctx.Diags.diagnose(expr->getLoc(), diag::broken_stdlib_type,
7288
+ toType->getAnyNominal()->getName().str());
7289
+ auto *errorExpr = new (ctx) ErrorExpr(SourceRange(), toType);
7290
+ cs.setType(errorExpr, toType);
7327
7291
7328
- solution.overloadChoices.insert({memberLoc, overload}) ;
7292
+ return errorExpr ;
7329
7293
}
7330
7294
7331
- // Record the implicit call's parameter bindings and match direction.
7332
- solution.recordSingleArgMatchingChoice(callLocator);
7295
+ auto *ctorRefExpr = new (ctx) DeclRefExpr(decl, DeclNameLoc(), /*Implicit=*/true);
7296
+ ctorRefExpr->setType(decl->getInterfaceType());
7297
+ auto *typeExpr = TypeExpr::createImplicit(toType, ctx);
7298
+ auto *innerCall = ConstructorRefCallExpr::create(ctx, ctorRefExpr, typeExpr,
7299
+ decl->getMethodInterfaceType());
7300
+ cs.cacheExprTypes(innerCall);
7301
+
7302
+ auto *argList = ArgumentList::forImplicitUnlabeled(ctx, {cs.coerceToRValue(expr)});
7303
+ auto *outerCall = CallExpr::createImplicit(ctx, innerCall, argList);
7304
+ outerCall->setType(toType);
7305
+ cs.setType(outerCall, toType);
7333
7306
7334
- finishApply(implicitInit, toType, callLocator, callLocator);
7335
- return implicitInit;
7307
+ return outerCall;
7336
7308
}
7337
7309
}
7338
7310
}
0 commit comments