Skip to content

Commit f9eb71d

Browse files
committed
[ConstraintSystem] Attempt Double <-> CGFloat implicit conversion only once and re-use results
1 parent 7aed970 commit f9eb71d

File tree

3 files changed

+53
-17
lines changed

3 files changed

+53
-17
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,8 +553,12 @@ template <typename T = Expr> T *castToExpr(ASTNode node) {
553553
}
554554

555555
template <typename T = Expr> T *getAsExpr(ASTNode node) {
556+
if (node.isNull())
557+
return nullptr;
558+
556559
if (auto *E = node.dyn_cast<Expr *>())
557560
return dyn_cast_or_null<T>(E);
561+
558562
return nullptr;
559563
}
560564

lib/Sema/CSApply.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6692,21 +6692,23 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
66926692

66936693
case ConversionRestrictionKind::CGFloatToDouble:
66946694
case ConversionRestrictionKind::DoubleToCGFloat: {
6695-
auto *fnExpr = TypeExpr::createImplicit(toType, ctx);
6696-
cs.cacheExprTypes(fnExpr);
6695+
auto conversionKind = knownRestriction->second;
66976696

66986697
auto *argExpr = locator.trySimplifyToExpr();
66996698
assert(argExpr);
67006699

6701-
auto *callLocator = cs.getConstraintLocator(
6702-
locator,
6703-
LocatorPathElt::ImplicitConversion(knownRestriction->second));
6704-
67056700
auto *implicitInit =
6706-
CallExpr::createImplicit(ctx, fnExpr,
6701+
CallExpr::createImplicit(ctx, TypeExpr::createImplicit(toType, ctx),
67076702
/*args=*/{argExpr},
67086703
/*argLabels=*/{Identifier()});
6709-
cs.cacheExprTypes(implicitInit);
6704+
6705+
cs.cacheExprTypes(implicitInit->getFn());
6706+
cs.setType(argExpr, fromType);
6707+
cs.setType(implicitInit->getArg(),
6708+
ParenType::get(cs.getASTContext(), fromType));
6709+
6710+
auto *callLocator = cs.getConstraintLocator(
6711+
implicitInit, LocatorPathElt::ImplicitConversion(conversionKind));
67106712

67116713
// HACK: Temporarily push the call expr onto the expr stack to make sure
67126714
// we don't try to prematurely close an existential when applying the
@@ -6715,6 +6717,25 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
67156717
ExprStack.push_back(implicitInit);
67166718
SWIFT_DEFER { ExprStack.pop_back(); };
67176719

6720+
// We need to take information recorded for all conversions of this
6721+
// kind and move it to a specific location where restriction is applied.
6722+
{
6723+
auto *memberLoc = solution.getConstraintLocator(
6724+
callLocator, {ConstraintLocator::ApplyFunction,
6725+
ConstraintLocator::ConstructorMember});
6726+
6727+
auto overload = solution.getOverloadChoice(cs.getConstraintLocator(
6728+
ASTNode(), {LocatorPathElt::ImplicitConversion(conversionKind),
6729+
ConstraintLocator::ApplyFunction,
6730+
ConstraintLocator::ConstructorMember}));
6731+
6732+
solution.overloadChoices.insert({memberLoc, overload});
6733+
solution.trailingClosureMatchingChoices.insert(
6734+
{cs.getConstraintLocator(callLocator,
6735+
ConstraintLocator::ApplyArgument),
6736+
TrailingClosureMatching::Forward});
6737+
}
6738+
67186739
finishApply(implicitInit, toType, callLocator, callLocator);
67196740
return implicitInit;
67206741
}

lib/Sema/CSSimplify.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,12 +1345,6 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
13451345
}
13461346
}
13471347

1348-
// If this application is part of an operator, then we allow an implicit
1349-
// lvalue to be compatible with inout arguments. This is used by
1350-
// assignment operators.
1351-
auto anchor = locator.getAnchor();
1352-
assert(bool(anchor) && "locator without anchor?");
1353-
13541348
auto isSynthesizedArgument = [](const AnyFunctionType::Param &arg) -> bool {
13551349
if (auto *typeVar = arg.getPlainType()->getAs<TypeVariableType>()) {
13561350
auto *locator = typeVar->getImpl().getLocator();
@@ -10534,13 +10528,30 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1053410528
if (worseThanBestSolution())
1053510529
return SolutionKind::Error;
1053610530

10537-
auto *applicationLoc = getConstraintLocator(
10538-
locator, {LocatorPathElt::ImplicitConversion(restriction),
10539-
ConstraintLocator::ApplyFunction});
10531+
auto *conversionLoc = getConstraintLocator(
10532+
/*anchor=*/ASTNode(), LocatorPathElt::ImplicitConversion(restriction));
10533+
10534+
auto *applicationLoc =
10535+
getConstraintLocator(conversionLoc, ConstraintLocator::ApplyFunction);
1054010536

1054110537
auto *memberLoc = getConstraintLocator(
1054210538
applicationLoc, ConstraintLocator::ConstructorMember);
1054310539

10540+
// This conversion has been already attempted for and constructor
10541+
// choice has been recorded.
10542+
if (findSelectedOverloadFor(memberLoc))
10543+
return SolutionKind::Solved;
10544+
10545+
// Allocate a single argument info to conver all possible
10546+
// Double <-> CGFloat conversion locations.
10547+
if (!ArgumentInfos.count(memberLoc)) {
10548+
auto &ctx = getASTContext();
10549+
ArgumentInfo callInfo{.Labels = ctx.Allocate<Identifier>(
10550+
1, AllocationArena::ConstraintSolver),
10551+
.UnlabeledTrailingClosureIndex = None};
10552+
ArgumentInfos.insert({memberLoc, std::move(callInfo)});
10553+
}
10554+
1054410555
auto *memberTy = createTypeVariable(memberLoc, TVO_CanBindToNoEscape);
1054510556

1054610557
addValueMemberConstraint(MetatypeType::get(type2, getASTContext()),

0 commit comments

Comments
 (0)