Skip to content

Commit 7f90290

Browse files
committed
[Constraint system] Adopt rewriteTarget for function builder transform.
When applying a function builder to a closure to produce the final, type-checked closure, use the new rewriteTarget() so it’s performed on a per-target basis. Use this to eliminate some duplicating in the handling of return types.
1 parent efd357e commit 7f90290

File tree

3 files changed

+54
-39
lines changed

3 files changed

+54
-39
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -627,8 +627,9 @@ class BuilderClosureRewriter
627627
const Solution &solution;
628628
DeclContext *dc;
629629
AppliedBuilderTransform builderTransform;
630-
std::function<Expr *(Expr *)> rewriteExpr;
631-
std::function<Expr *(Expr *, Type, ConstraintLocator *)> coerceToType;
630+
std::function<
631+
Optional<SolutionApplicationTarget> (SolutionApplicationTarget)>
632+
rewriteTarget;
632633

633634
/// Retrieve the temporary variable that will be used to capture the
634635
/// value of the given expression.
@@ -648,6 +649,17 @@ class BuilderClosureRewriter
648649
return recorded;
649650
}
650651

652+
/// Rewrite an expression without any particularly special context.
653+
Expr *rewriteExpr(Expr *expr) {
654+
auto result = rewriteTarget(
655+
SolutionApplicationTarget(expr, dc, CTP_Unused, Type(),
656+
/*isDiscarded=*/false));
657+
if (result)
658+
return result->getAsExpr();
659+
660+
return nullptr;
661+
}
662+
651663
public:
652664
/// Retrieve information about a captured statement.
653665
std::pair<VarDecl *, llvm::TinyPtrVector<Expr *>>
@@ -673,19 +685,21 @@ class BuilderClosureRewriter
673685
ASTNode initializeTarget(FunctionBuilderTarget target) {
674686
assert(target.captured.second.size() == 1);
675687
auto capturedExpr = target.captured.second.front();
676-
auto finalCapturedExpr = rewriteExpr(capturedExpr);
677688
SourceLoc implicitLoc = capturedExpr->getEndLoc();
678689
switch (target.kind) {
679690
case FunctionBuilderTarget::ReturnValue: {
680691
// Return the expression.
681-
ConstraintSystem &cs = solution.getConstraintSystem();
682692
Type bodyResultType =
683693
solution.simplifyType(builderTransform.bodyResultType);
684-
finalCapturedExpr = coerceToType(
685-
finalCapturedExpr,
686-
bodyResultType,
687-
cs.getConstraintLocator(capturedExpr));
688-
return new (ctx) ReturnStmt(implicitLoc, finalCapturedExpr);
694+
695+
SolutionApplicationTarget returnTarget(
696+
capturedExpr, dc, CTP_ReturnStmt, bodyResultType,
697+
/*isDiscarded=*/false);
698+
Expr *resultExpr = nullptr;
699+
if (auto resultTarget = rewriteTarget(returnTarget))
700+
resultExpr = resultTarget->getAsExpr();
701+
702+
return new (ctx) ReturnStmt(implicitLoc, resultExpr);
689703
}
690704

691705
case FunctionBuilderTarget::TemporaryVar: {
@@ -696,6 +710,7 @@ class BuilderClosureRewriter
696710
declRef->setType(LValueType::get(temporaryVar->getType()));
697711

698712
// Load the right-hand side if needed.
713+
auto finalCapturedExpr = rewriteExpr(capturedExpr);
699714
if (finalCapturedExpr->getType()->hasLValueType()) {
700715
finalCapturedExpr =
701716
TypeChecker::addImplicitLoadExpr(ctx, finalCapturedExpr);
@@ -734,12 +749,12 @@ class BuilderClosureRewriter
734749
const Solution &solution,
735750
DeclContext *dc,
736751
const AppliedBuilderTransform &builderTransform,
737-
std::function<Expr *(Expr *)> rewriteExpr,
738-
std::function<Expr *(Expr *, Type, ConstraintLocator *)> coerceToType
752+
std::function<
753+
Optional<SolutionApplicationTarget> (SolutionApplicationTarget)>
754+
rewriteTarget
739755
) : ctx(solution.getConstraintSystem().getASTContext()),
740756
solution(solution), dc(dc), builderTransform(builderTransform),
741-
rewriteExpr(rewriteExpr),
742-
coerceToType(coerceToType){ }
757+
rewriteTarget(rewriteTarget) { }
743758

744759
Stmt *visitBraceStmt(BraceStmt *braceStmt, FunctionBuilderTarget target,
745760
Optional<FunctionBuilderTarget> innerTarget = None) {
@@ -954,9 +969,10 @@ BraceStmt *swift::applyFunctionBuilderTransform(
954969
AppliedBuilderTransform applied,
955970
BraceStmt *body,
956971
DeclContext *dc,
957-
std::function<Expr *(Expr *)> rewriteExpr,
958-
std::function<Expr *(Expr *, Type, ConstraintLocator *)> coerceToType) {
959-
BuilderClosureRewriter rewriter(solution, dc, applied, rewriteExpr, coerceToType);
972+
std::function<
973+
Optional<SolutionApplicationTarget> (SolutionApplicationTarget)>
974+
rewriteTarget) {
975+
BuilderClosureRewriter rewriter(solution, dc, applied, rewriteTarget);
960976
auto captured = rewriter.takeCapturedStmt(body);
961977
return cast<BraceStmt>(
962978
rewriter.visitBraceStmt(

lib/Sema/CSApply.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7063,14 +7063,14 @@ namespace {
70637063
llvm::SaveAndRestore<DeclContext *> savedDC(Rewriter.dc, closure);
70647064
auto newBody = applyFunctionBuilderTransform(
70657065
Rewriter.solution, *transform, closure->getBody(), closure,
7066-
[&](Expr *expr) {
7067-
Expr *result = expr->walk(*this);
7068-
if (result)
7069-
Rewriter.solution.setExprTypes(result);
7070-
return result;
7071-
},
7072-
[&](Expr *expr, Type toType, ConstraintLocator *locator) {
7073-
return Rewriter.coerceToType(expr, toType, locator);
7066+
[&](SolutionApplicationTarget target) {
7067+
auto resultTarget = rewriteTarget(target);
7068+
if (resultTarget) {
7069+
if (auto expr = resultTarget->getAsExpr())
7070+
Rewriter.solution.setExprTypes(expr);
7071+
}
7072+
7073+
return resultTarget;
70747074
});
70757075
closure->setBody(newBody, /*isSingleExpression=*/false);
70767076
closure->setAppliedFunctionBuilder();
@@ -7340,14 +7340,14 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
73407340

73417341
auto newBody = applyFunctionBuilderTransform(
73427342
solution, *transform, fn.getBody(), fn.getAsDeclContext(),
7343-
[&](Expr *expr) {
7344-
Expr *result = expr->walk(*this);
7345-
if (result)
7346-
solution.setExprTypes(result);
7347-
return result;
7348-
},
7349-
[&](Expr *expr, Type toType, ConstraintLocator *locator) {
7350-
return Rewriter.coerceToType(expr, toType, locator);
7343+
[&](SolutionApplicationTarget target) {
7344+
auto resultTarget = rewriteTarget(target);
7345+
if (resultTarget) {
7346+
if (auto expr = resultTarget->getAsExpr())
7347+
Rewriter.solution.setExprTypes(expr);
7348+
}
7349+
7350+
return resultTarget;
73517351
});
73527352

73537353
if (!newBody)

lib/Sema/ConstraintSystem.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5067,20 +5067,19 @@ bool isSIMDOperator(ValueDecl *value);
50675067
/// \param applied The applied builder transform.
50685068
/// \param body The body to transform
50695069
/// \param dc The context in which the transform occurs.
5070-
/// \param rewriteExpr Rewrites expressions that show up in the transform
5071-
/// to their final, type-checked versions.
5072-
/// \param coerceToType Coerce the given expression to the specified type,
5073-
/// which may introduce implicit conversions.
5070+
/// \param rewriteTarget Rewrites a solution application target to its final,
5071+
/// type-checked version.
50745072
///
50755073
/// \returns the transformed body
50765074
BraceStmt *applyFunctionBuilderTransform(
50775075
const constraints::Solution &solution,
50785076
constraints::AppliedBuilderTransform applied,
50795077
BraceStmt *body,
50805078
DeclContext *dc,
5081-
std::function<Expr *(Expr *)> rewriteExpr,
5082-
std::function<Expr *(Expr *, Type, constraints::ConstraintLocator *)>
5083-
coerceToType);
5079+
std::function<
5080+
Optional<constraints::SolutionApplicationTarget> (
5081+
constraints::SolutionApplicationTarget)>
5082+
rewriteTarget);
50845083

50855084
} // end namespace swift
50865085

0 commit comments

Comments
 (0)