@@ -4162,7 +4162,7 @@ namespace {
41624162
41634163 // SIL-generation magically turns this into a Bool; make sure it can.
41644164 if (!ctx.getBoolBuiltinInitDecl ()) {
4165- ctx.Diags .diagnose (expr->getLoc (), diag::broken_bool );
4165+ ctx.Diags .diagnose (expr->getLoc (), diag::broken_stdlib_type, " Bool " );
41664166 // Continue anyway.
41674167 }
41684168
@@ -4200,7 +4200,7 @@ namespace {
42004200 auto boolDecl = ctx.getBoolDecl ();
42014201
42024202 if (!boolDecl) {
4203- ctx.Diags .diagnose (SourceLoc (), diag::broken_bool );
4203+ ctx.Diags .diagnose (SourceLoc (), diag::broken_stdlib_type, " Bool " );
42044204 }
42054205
42064206 cs.setType (isSomeExpr, boolDecl ? ctx.getBoolType () : Type ());
@@ -5868,6 +5868,9 @@ static unsigned getOptionalEvaluationDepth(Expr *expr, Expr *target) {
58685868 depth += getOptionalEvaluationDepth (open->getSubExpr (),
58695869 open->getOpaqueValue ());
58705870 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 );
58715874
58725875 // Otherwise, look through implicit conversions.
58735876 } else {
@@ -7262,77 +7265,46 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
72627265
72637266 case ConversionRestrictionKind::CGFloatToDouble:
72647267 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+ }
73227285
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);
73277291
7328- solution. overloadChoices . insert ({memberLoc, overload}) ;
7292+ return errorExpr ;
73297293 }
73307294
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);
73337306
7334- finishApply (implicitInit, toType, callLocator, callLocator);
7335- return implicitInit;
7307+ return outerCall;
73367308 }
73377309 }
73387310 }
0 commit comments