Skip to content

Commit 0c2887d

Browse files
committed
Sema: Simplify CSApply for Double<->CGFloat conversion
1 parent c47ff06 commit 0c2887d

File tree

4 files changed

+41
-71
lines changed

4 files changed

+41
-71
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4544,7 +4544,8 @@ ERROR(try_assign_rhs_noncovering,none,
45444544
"'" TRY_KIND_SELECT(0) "' following assignment operator does not cover "
45454545
"everything to its right", (unsigned))
45464546

4547-
ERROR(broken_bool,none, "type 'Bool' is broken", ())
4547+
ERROR(broken_stdlib_type,none,
4548+
"standard library type '%0' is missing or broken; this is a compiler bug", (StringRef))
45484549

45494550
WARNING(inject_forced_downcast,none,
45504551
"treating a forced downcast to %0 as optional will never produce 'nil'",

lib/Sema/CSApply.cpp

Lines changed: 37 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -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());
@@ -7262,77 +7262,46 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
72627262

72637263
case ConversionRestrictionKind::CGFloatToDouble:
72647264
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);
7265+
DeclName name(ctx, DeclBaseName::createConstructor(), Identifier());
7266+
7267+
ConstructorDecl *decl = nullptr;
7268+
SmallVector<ValueDecl *, 2> candidates;
7269+
dc->lookupQualified(toType->getAnyNominal(),
7270+
DeclNameRef(name), SourceLoc(),
7271+
NL_QualifiedDefault, candidates);
7272+
for (auto *candidate : candidates) {
7273+
auto *ctor = cast<ConstructorDecl>(candidate);
7274+
auto fnType = ctor->getMethodInterfaceType()->castTo<FunctionType>();
7275+
if (fnType->getNumParams() == 1 &&
7276+
fnType->getParams()[0].getPlainType()->isEqual(fromType) &&
7277+
fnType->getResult()->isEqual(toType)) {
7278+
decl = ctor;
7279+
break;
7280+
}
7281+
}
73227282

7323-
auto overload =
7324-
solution.getOverloadChoice(solution.getConstraintLocator(
7325-
baseLoc, {ConstraintLocator::ApplyFunction,
7326-
ConstraintLocator::ConstructorMember}));
7283+
if (decl == nullptr) {
7284+
ctx.Diags.diagnose(expr->getLoc(), diag::broken_stdlib_type,
7285+
toType->getAnyNominal()->getName().str());
7286+
auto *errorExpr = new (ctx) ErrorExpr(SourceRange(), toType);
7287+
cs.setType(errorExpr, toType);
73277288

7328-
solution.overloadChoices.insert({memberLoc, overload});
7289+
return errorExpr;
73297290
}
73307291

7331-
// Record the implicit call's parameter bindings and match direction.
7332-
solution.recordSingleArgMatchingChoice(callLocator);
7292+
auto *ctorRefExpr = new (ctx) DeclRefExpr(decl, DeclNameLoc(), /*Implicit=*/true);
7293+
ctorRefExpr->setType(decl->getInterfaceType());
7294+
auto *typeExpr = TypeExpr::createImplicit(toType, ctx);
7295+
auto *innerCall = ConstructorRefCallExpr::create(ctx, ctorRefExpr, typeExpr,
7296+
decl->getMethodInterfaceType());
7297+
cs.cacheExprTypes(innerCall);
7298+
7299+
auto *argList = ArgumentList::forImplicitUnlabeled(ctx, {cs.coerceToRValue(expr)});
7300+
auto *outerCall = CallExpr::createImplicit(ctx, innerCall, argList);
7301+
outerCall->setType(toType);
7302+
cs.setType(outerCall, toType);
73337303

7334-
finishApply(implicitInit, toType, callLocator, callLocator);
7335-
return implicitInit;
7304+
return outerCall;
73367305
}
73377306
}
73387307
}

lib/Sema/CSGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2683,7 +2683,7 @@ namespace {
26832683
auto boolDecl = ctx.getBoolDecl();
26842684

26852685
if (!boolDecl) {
2686-
ctx.Diags.diagnose(SourceLoc(), diag::broken_bool);
2686+
ctx.Diags.diagnose(SourceLoc(), diag::broken_stdlib_type, "Bool");
26872687
return Type();
26882688
}
26892689

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -936,7 +936,7 @@ bool swift::isRepresentableInObjC(
936936
boolDecl = ctx.getBoolDecl();
937937

938938
if (boolDecl == nullptr) {
939-
AFD->diagnose(diag::broken_bool);
939+
AFD->diagnose(diag::broken_stdlib_type, "Bool");
940940
return false;
941941
}
942942

0 commit comments

Comments
 (0)