Skip to content

Commit 852e3f5

Browse files
authored
Merge pull request swiftlang#78957 from slavapestov/cgfloat-double-cleanup
Sema: Clean up CSApply for CGFloat <-> Double conversion
2 parents 6f6742f + 5cbe8cb commit 852e3f5

File tree

9 files changed

+67
-191
lines changed

9 files changed

+67
-191
lines changed

include/swift/AST/DiagnosticsSema.def

+2-1
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'",

include/swift/Sema/CSTrail.def

-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ LOCATOR_CHANGE(RecordedOpenedExistentialType, OpenedExistentialTypes)
5454
LOCATOR_CHANGE(RecordedPackExpansionEnvironment, PackExpansionEnvironments)
5555
LOCATOR_CHANGE(RecordedDefaultedConstraint, DefaultedConstraints)
5656
LOCATOR_CHANGE(ResolvedOverload, ResolvedOverloads)
57-
LOCATOR_CHANGE(RecordedImplicitValueConversion, ImplicitValueConversions)
5857
LOCATOR_CHANGE(RecordedArgumentList, ArgumentLists)
5958
LOCATOR_CHANGE(RecordedImplicitCallAsFunctionRoot, ImplicitCallAsFunctionRoots)
6059
LOCATOR_CHANGE(RecordedSynthesizedConformance, SynthesizedConformances)

include/swift/Sema/ConstraintSystem.h

+6-20
Original file line numberDiff line numberDiff line change
@@ -1580,10 +1580,6 @@ class Solution {
15801580
/// The locators of \c Defaultable constraints whose defaults were used.
15811581
llvm::DenseSet<ConstraintLocator *> DefaultedConstraints;
15821582

1583-
/// Implicit value conversions applied for a given locator.
1584-
std::vector<std::pair<ConstraintLocator *, ConversionRestrictionKind>>
1585-
ImplicitValueConversions;
1586-
15871583
/// The node -> type mappings introduced by this solution.
15881584
llvm::DenseMap<ASTNode, Type> nodeTypes;
15891585

@@ -2368,11 +2364,6 @@ class ConstraintSystem {
23682364
llvm::DenseMap<ConstraintLocator *, MatchCallArgumentResult>
23692365
argumentMatchingChoices;
23702366

2371-
/// The set of implicit value conversions performed by the solver on
2372-
/// a current path to reach a solution.
2373-
llvm::SmallDenseMap<ConstraintLocator *, ConversionRestrictionKind, 2>
2374-
ImplicitValueConversions;
2375-
23762367
/// The worklist of "active" constraints that should be revisited
23772368
/// due to a change.
23782369
ConstraintList ActiveConstraints;
@@ -4608,16 +4599,15 @@ class ConstraintSystem {
46084599
inline bool isFailure() const { return Kind == SolutionKind::Error; }
46094600
inline bool isAmbiguous() const { return Kind == SolutionKind::Unsolved; }
46104601

4611-
static TypeMatchResult success(ConstraintSystem &cs) {
4602+
static TypeMatchResult success() {
46124603
return {SolutionKind::Solved};
46134604
}
46144605

4615-
static TypeMatchResult failure(ConstraintSystem &cs,
4616-
ConstraintLocatorBuilder location) {
4606+
static TypeMatchResult failure() {
46174607
return {SolutionKind::Error};
46184608
}
46194609

4620-
static TypeMatchResult ambiguous(ConstraintSystem &cs) {
4610+
static TypeMatchResult ambiguous() {
46214611
return {SolutionKind::Unsolved};
46224612
}
46234613

@@ -4722,15 +4712,15 @@ class ConstraintSystem {
47224712
ConstraintLocatorBuilder locator);
47234713

47244714
TypeMatchResult getTypeMatchSuccess() {
4725-
return TypeMatchResult::success(*this);
4715+
return TypeMatchResult::success();
47264716
}
47274717

47284718
TypeMatchResult getTypeMatchFailure(ConstraintLocatorBuilder locator) {
4729-
return TypeMatchResult::failure(*this, locator);
4719+
return TypeMatchResult::failure();
47304720
}
47314721

47324722
TypeMatchResult getTypeMatchAmbiguous() {
4733-
return TypeMatchResult::ambiguous(*this);
4723+
return TypeMatchResult::ambiguous();
47344724
}
47354725

47364726
public:
@@ -5047,10 +5037,6 @@ class ConstraintSystem {
50475037
TypeMatchOptions flags,
50485038
ConstraintLocatorBuilder locator);
50495039

5050-
/// Update ImplicitValueConversions and record a change in the trail.
5051-
void recordImplicitValueConversion(ConstraintLocator *locator,
5052-
ConversionRestrictionKind restriction);
5053-
50545040
/// Simplify a conversion constraint by applying the given
50555041
/// reduction rule, which is known to apply at the outermost level.
50565042
SolutionKind simplifyRestrictedConstraint(

lib/Sema/CSApply.cpp

+40-68
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());
@@ -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
}

lib/Sema/CSGen.cpp

+1-1
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/CSSimplify.cpp

+17-67
Original file line numberDiff line numberDiff line change
@@ -7646,6 +7646,22 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
76467646
}
76477647
}
76487648

7649+
if (kind == ConstraintKind::BindToPointerType) {
7650+
if (desugar2->isEqual(getASTContext().TheEmptyTupleType))
7651+
return getTypeMatchSuccess();
7652+
}
7653+
7654+
if (kind == ConstraintKind::BindParam) {
7655+
if (auto *iot = dyn_cast<InOutType>(desugar1)) {
7656+
if (auto *lvt = dyn_cast<LValueType>(desugar2)) {
7657+
return matchTypes(iot->getObjectType(), lvt->getObjectType(),
7658+
ConstraintKind::Bind, subflags,
7659+
locator.withPathElement(
7660+
ConstraintLocator::LValueConversion));
7661+
}
7662+
}
7663+
}
7664+
76497665
if (kind >= ConstraintKind::Conversion) {
76507666
// An lvalue of type T1 can be converted to a value of type T2 so long as
76517667
// T1 is convertible to T2 (by loading the value). Note that we cannot get
@@ -7777,7 +7793,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
77777793
}
77787794

77797795
// Special implicit nominal conversions.
7780-
if (!type1->is<LValueType>() && kind >= ConstraintKind::Subtype) {
7796+
if (!type1->is<LValueType>()) {
77817797
// Array -> Array.
77827798
if (desugar1->isArray() && desugar2->isArray()) {
77837799
conversionsOrFixes.push_back(ConversionRestrictionKind::ArrayUpcast);
@@ -7793,11 +7809,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
77937809
}
77947810
}
77957811

7796-
if (kind == ConstraintKind::BindToPointerType) {
7797-
if (desugar2->isEqual(getASTContext().TheEmptyTupleType))
7798-
return getTypeMatchSuccess();
7799-
}
7800-
78017812
if (kind >= ConstraintKind::Conversion) {
78027813
// It is never legal to form an autoclosure that results in these
78037814
// implicit conversions to pointer types.
@@ -8054,17 +8065,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
80548065
}
80558066
}
80568067

8057-
if (kind == ConstraintKind::BindParam) {
8058-
if (auto *iot = dyn_cast<InOutType>(desugar1)) {
8059-
if (auto *lvt = dyn_cast<LValueType>(desugar2)) {
8060-
return matchTypes(iot->getObjectType(), lvt->getObjectType(),
8061-
ConstraintKind::Bind, subflags,
8062-
locator.withPathElement(
8063-
ConstraintLocator::LValueConversion));
8064-
}
8065-
}
8066-
}
8067-
80688068
// Matching types where one side is a pack expansion and the other is not
80698069
// means a pack expansion was used where it isn't supported.
80708070
if (type1->is<PackExpansionType>() != type2->is<PackExpansionType>()) {
@@ -14263,17 +14263,6 @@ void ConstraintSystem::addRestrictedConstraint(
1426314263
TMF_GenerateConstraints, locator);
1426414264
}
1426514265

14266-
void ConstraintSystem::recordImplicitValueConversion(
14267-
ConstraintLocator *locator,
14268-
ConversionRestrictionKind restriction) {
14269-
bool inserted = ImplicitValueConversions.insert(
14270-
{getConstraintLocator(locator), restriction}).second;
14271-
ASSERT(inserted);
14272-
14273-
if (solverState)
14274-
recordChange(SolverTrail::Change::RecordedImplicitValueConversion(locator));
14275-
}
14276-
1427714266
/// Given that we have a conversion constraint between two types, and
1427814267
/// that the given constraint-reduction rule applies between them at
1427914268
/// the top level, apply it and generate any necessary recursive
@@ -14850,45 +14839,6 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1485014839
if (worseThanBestSolution())
1485114840
return SolutionKind::Error;
1485214841

14853-
auto *conversionLoc =
14854-
getImplicitValueConversionLocator(locator, restriction);
14855-
14856-
auto *applicationLoc =
14857-
getConstraintLocator(conversionLoc, ConstraintLocator::ApplyFunction);
14858-
14859-
auto *memberLoc = getConstraintLocator(
14860-
applicationLoc, ConstraintLocator::ConstructorMember);
14861-
14862-
// Allocate a single argument info to cover all possible
14863-
// Double <-> CGFloat conversion locations.
14864-
auto *argumentsLoc =
14865-
getConstraintLocator(conversionLoc, ConstraintLocator::ApplyArgument);
14866-
14867-
if (!ArgumentLists.count(argumentsLoc)) {
14868-
auto *argList = ArgumentList::createImplicit(
14869-
getASTContext(), {Argument(SourceLoc(), Identifier(), nullptr)},
14870-
/*firstTrailingClosureIndex=*/std::nullopt,
14871-
AllocationArena::ConstraintSolver);
14872-
recordArgumentList(argumentsLoc, argList);
14873-
}
14874-
14875-
auto *memberTypeLoc = getConstraintLocator(
14876-
applicationLoc, LocatorPathElt::ConstructorMemberType());
14877-
14878-
auto *memberTy = createTypeVariable(memberTypeLoc, TVO_CanBindToNoEscape);
14879-
14880-
addValueMemberConstraint(MetatypeType::get(type2, getASTContext()),
14881-
DeclNameRef(DeclBaseName::createConstructor()),
14882-
memberTy, DC,
14883-
FunctionRefInfo::doubleBaseNameApply(),
14884-
/*outerAlternatives=*/{}, memberLoc);
14885-
14886-
addConstraint(ConstraintKind::ApplicableFunction,
14887-
FunctionType::get({FunctionType::Param(type1)}, type2),
14888-
memberTy, applicationLoc);
14889-
14890-
ImplicitValueConversions.insert(
14891-
{getConstraintLocator(locator), restriction});
1489214842
return SolutionKind::Solved;
1489314843
}
1489414844
}

lib/Sema/CSSolver.cpp

-12
Original file line numberDiff line numberDiff line change
@@ -243,11 +243,6 @@ Solution ConstraintSystem::finalize() {
243243
solution.appliedPropertyWrappers.insert(appliedWrapper);
244244
}
245245

246-
// Remember implicit value conversions.
247-
for (const auto &valueConversion : ImplicitValueConversions) {
248-
solution.ImplicitValueConversions.push_back(valueConversion);
249-
}
250-
251246
// Remember argument lists.
252247
for (const auto &argListMapping : ArgumentLists) {
253248
solution.argumentLists.insert(argListMapping);
@@ -445,13 +440,6 @@ void ConstraintSystem::replaySolution(const Solution &solution,
445440
}
446441
}
447442

448-
for (auto &valueConversion : solution.ImplicitValueConversions) {
449-
if (ImplicitValueConversions.count(valueConversion.first) == 0) {
450-
recordImplicitValueConversion(valueConversion.first,
451-
valueConversion.second);
452-
}
453-
}
454-
455443
// Register the argument lists.
456444
for (auto &argListMapping : solution.argumentLists) {
457445
if (ArgumentLists.count(argListMapping.first) == 0)

0 commit comments

Comments
 (0)