Skip to content

Commit 2fc2b15

Browse files
committed
[Function builders] Align buildDo() implementation with the pitch.
Rather than passing the result of buildBlock() into buildDo(), follow the (better) design from the function builders pitch by passing in the components from the block directly into buildDo(). This means that buildDo() will need to take separate parameters for each component, but allows buildDo() to treat the components separately.
1 parent fa2d4dc commit 2fc2b15

File tree

2 files changed

+25
-9
lines changed

2 files changed

+25
-9
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,10 @@ class BuilderClosureVisitor
293293
}
294294

295295
VarDecl *visitBraceStmt(BraceStmt *braceStmt) {
296+
return visitBraceStmt(braceStmt, ctx.Id_buildBlock);
297+
}
298+
299+
VarDecl *visitBraceStmt(BraceStmt *braceStmt, Identifier builderFunction) {
296300
SmallVector<Expr *, 4> expressions;
297301
auto addChild = [&](VarDecl *childVar) {
298302
if (!childVar)
@@ -359,7 +363,7 @@ class BuilderClosureVisitor
359363

360364
// Call Builder.buildBlock(... args ...)
361365
auto call = buildCallIfWanted(braceStmt->getStartLoc(),
362-
ctx.Id_buildBlock, expressions,
366+
builderFunction, expressions,
363367
/*argLabels=*/{ });
364368
if (!call)
365369
return nullptr;
@@ -380,17 +384,13 @@ class BuilderClosureVisitor
380384
return nullptr;
381385
}
382386

383-
auto childVar = visit(doStmt->getBody());
387+
auto childVar = visitBraceStmt(doStmt->getBody(), ctx.Id_buildDo);
384388
if (!childVar)
385389
return nullptr;
386390

387391
auto childRef = buildVarRef(childVar, doStmt->getEndLoc());
388-
auto call = buildCallIfWanted(doStmt->getStartLoc(), ctx.Id_buildDo,
389-
childRef, /*argLabels=*/{ });
390-
if (!call)
391-
return nullptr;
392392

393-
return captureExpr(call, /*oneWay=*/true, doStmt);
393+
return captureExpr(childRef, /*oneWay=*/true, doStmt);
394394
}
395395

396396
CONTROL_FLOW_STMT(Yield)

test/Constraints/function_builder.swift

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ enum Either<T,U> {
66
case second(U)
77
}
88

9+
struct Do<T> {
10+
var value: T
11+
}
12+
913
@_functionBuilder
1014
struct TupleBuilder {
1115
static func buildBlock<T1>(_ t1: T1) -> (T1) {
@@ -32,7 +36,19 @@ struct TupleBuilder {
3236
return (t1, t2, t3, t4, t5)
3337
}
3438

35-
static func buildDo<T>(_ value: T) -> T { return value }
39+
static func buildDo<T1>(_ t1: T1) -> Do<(T1)> {
40+
.init(value: t1)
41+
}
42+
43+
static func buildDo<T1, T2>(_ t1: T1, _ t2: T2) -> Do<(T1, T2)> {
44+
.init(value: (t1, t2))
45+
}
46+
47+
static func buildDo<T1, T2, T3>(_ t1: T1, _ t2: T2, _ t3: T3)
48+
-> Do<(T1, T2, T3)> {
49+
.init(value: (t1, t2, t3))
50+
}
51+
3652
static func buildIf<T>(_ value: T?) -> T? { return value }
3753

3854
static func buildEither<T,U>(first value: T) -> Either<T,U> {
@@ -49,7 +65,7 @@ func tuplify<T>(_ cond: Bool, @TupleBuilder body: (Bool) -> T) {
4965
print(body(cond))
5066
}
5167

52-
// CHECK: (17, 3.14159, "Hello, DSL", (["nested", "do"], 6), Optional((2.71828, ["if", "stmt"])))
68+
// CHECK: (17, 3.14159, "Hello, DSL", main.Do<(Swift.Array<Swift.String>, Swift.Int)>(value: (["nested", "do"], 6)), Optional((2.71828, ["if", "stmt"])))
5369
let name = "dsl"
5470
tuplify(true) {
5571
17

0 commit comments

Comments
 (0)