Skip to content

Commit 64d0b18

Browse files
authored
Merge pull request #27716 from DougGregor/function-builders-build-expression
[Function builders] Add support for buildExpression().
2 parents b202766 + fd916f9 commit 64d0b18

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ IDENTIFIER_(bridgeToObjectiveC)
3434
IDENTIFIER(buildBlock)
3535
IDENTIFIER(buildDo)
3636
IDENTIFIER(buildEither)
37+
IDENTIFIER(buildExpression)
3738
IDENTIFIER(buildIf)
3839
IDENTIFIER(callAsFunction)
3940
IDENTIFIER(Change)

lib/Sema/BuilderTransform.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,15 @@ class BuilderClosureVisitor
169169
}
170170

171171
auto expr = node.get<Expr *>();
172-
if (wantExpr)
173-
expr = new (ctx) OneWayExpr(expr);
172+
if (wantExpr) {
173+
if (builderSupports(ctx.Id_buildExpression)) {
174+
expr = buildCallIfWanted(expr->getLoc(), ctx.Id_buildExpression,
175+
{ expr }, { Identifier() },
176+
/*allowOneWay=*/true);
177+
} else {
178+
expr = new (ctx) OneWayExpr(expr);
179+
}
180+
}
174181

175182
expressions.push_back(expr);
176183
}

test/Constraints/function_builder.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,51 @@ func testAcceptColorTagged(b: Bool, i: Int, s: String, d: Double) {
316316

317317
testAcceptColorTagged(b: true, i: 17, s: "Hello", d: 3.14159)
318318

319+
// Use buildExpression() when it's available.
320+
enum Component {
321+
case string(StaticString)
322+
case floating(Double)
323+
case color(Color)
324+
indirect case array([Component])
325+
indirect case optional(Component?)
326+
}
327+
328+
@_functionBuilder
329+
struct ComponentBuilder {
330+
static func buildExpression(_ string: StaticString) -> Component {
331+
return .string(string)
332+
}
333+
334+
static func buildExpression(_ float: Double) -> Component {
335+
return .floating(float)
336+
}
337+
338+
static func buildExpression(_ color: Color) -> Component {
339+
return .color(color)
340+
}
341+
342+
static func buildBlock(_ components: Component...) -> Component {
343+
return .array(components)
344+
}
345+
346+
static func buildIf(_ value: Component?) -> Component {
347+
return .optional(value)
348+
}
349+
}
350+
351+
func acceptComponentBuilder(@ComponentBuilder _ body: () -> Component) {
352+
print(body())
353+
}
354+
355+
acceptComponentBuilder {
356+
"hello"
357+
if true {
358+
3.14159
359+
}
360+
.red
361+
}
362+
// CHECK: array([main.Component.string("hello"), main.Component.optional(Optional(main.Component.array([main.Component.floating(3.14159)]))), main.Component.color(main.Color.red)])
363+
319364
// rdar://53325810
320365

321366
// Test that we don't have problems with expression pre-checking when

0 commit comments

Comments
 (0)