Skip to content

Commit 2f62eb8

Browse files
authored
Merge pull request swiftlang#32100 from DougGregor/function-builders-do-block
[Function builders] Align buildDo() implementation with the pitch.
2 parents 50c0534 + 014466d commit 2f62eb8

File tree

6 files changed

+40
-16
lines changed

6 files changed

+40
-16
lines changed

include/swift/AST/Stmt.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -539,11 +539,11 @@ class LabeledStmt : public Stmt {
539539
/// DoStmt - do statement, without any trailing clauses.
540540
class DoStmt : public LabeledStmt {
541541
SourceLoc DoLoc;
542-
Stmt *Body;
542+
BraceStmt *Body;
543543

544544
public:
545545
DoStmt(LabeledStmtInfo labelInfo, SourceLoc doLoc,
546-
Stmt *body, Optional<bool> implicit = None)
546+
BraceStmt *body, Optional<bool> implicit = None)
547547
: LabeledStmt(StmtKind::Do, getDefaultImplicitFlag(implicit, doLoc),
548548
labelInfo),
549549
DoLoc(doLoc), Body(body) {}
@@ -553,8 +553,8 @@ class DoStmt : public LabeledStmt {
553553
SourceLoc getStartLoc() const { return getLabelLocOrKeywordLoc(DoLoc); }
554554
SourceLoc getEndLoc() const { return Body->getEndLoc(); }
555555

556-
Stmt *getBody() const { return Body; }
557-
void setBody(Stmt *s) { Body = s; }
556+
BraceStmt *getBody() const { return Body; }
557+
void setBody(BraceStmt *s) { Body = s; }
558558

559559
static bool classof(const Stmt *S) { return S->getKind() == StmtKind::Do; }
560560
};

lib/AST/ASTWalker.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1493,7 +1493,7 @@ Stmt *Traversal::visitGuardStmt(GuardStmt *US) {
14931493
}
14941494

14951495
Stmt *Traversal::visitDoStmt(DoStmt *DS) {
1496-
if (Stmt *S2 = doIt(DS->getBody()))
1496+
if (BraceStmt *S2 = cast_or_null<BraceStmt>(doIt(DS->getBody())))
14971497
DS->setBody(S2);
14981498
else
14991499
return nullptr;

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)

lib/Sema/TypeCheckStmt.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,7 @@ class StmtChecker : public StmtVisitor<StmtChecker, Stmt*> {
658658

659659
Stmt *visitDoStmt(DoStmt *DS) {
660660
AddLabeledStmt loopNest(*this, DS);
661-
Stmt *S = DS->getBody();
661+
BraceStmt *S = DS->getBody();
662662
typeCheckStmt(S);
663663
DS->setBody(S);
664664
return DS;

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

test/ModuleInterface/function_builders.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@ public struct TupleBuilder {
2626
return (t1, t2, t3, t4, t5)
2727
}
2828

29-
public static func buildDo<T>(_ value: T) -> T { return value }
29+
public static func buildDo<T1, T2>(_ t1: T1, _ t2: T2) -> (T1, T2) {
30+
return (t1, t2)
31+
}
32+
33+
public static func buildDo<T1, T2, T3>(_ t1: T1, _ t2: T2, _ t3: T3)
34+
-> (T1, T2, T3) {
35+
return (t1, t2, t3)
36+
}
37+
3038
public static func buildIf<T>(_ value: T?) -> T? { return value }
3139
}
3240

0 commit comments

Comments
 (0)