Skip to content

Commit d70f14e

Browse files
committed
[BuilderTransform] If: Save result of buildBlock into a variable before using in buildEither
Similar to `case` statements, if chain is non-optional, let's isolate `buildBlock` of every branch into a separate type variable.
1 parent 3add375 commit d70f14e

File tree

3 files changed

+28
-9
lines changed

3 files changed

+28
-9
lines changed

lib/Sema/BuilderTransform.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,8 @@ class ResultBuilderTransform
511511

512512
auto *ifBraceStmt = cast<BraceStmt>(ifStmt->getThenStmt());
513513

514-
std::tie(thenVarRef, unsupported) = transform(ifBraceStmt, thenBody);
514+
std::tie(thenVarRef, unsupported) =
515+
transform(ifBraceStmt, thenBody, /*isolateBuildBlock=*/true);
515516
if (unsupported) {
516517
recordUnsupported(*unsupported);
517518
return nullptr;
@@ -546,7 +547,8 @@ class ResultBuilderTransform
546547
auto *elseBraceStmt = cast<BraceStmt>(elseStmt);
547548
SmallVector<ASTNode> elseBody;
548549

549-
std::tie(elseVarRef, unsupported) = transform(elseBraceStmt, elseBody);
550+
std::tie(elseVarRef, unsupported) = transform(
551+
elseBraceStmt, elseBody, /*isolateBuildBlock=*/true);
550552
if (unsupported) {
551553
recordUnsupported(*unsupported);
552554
return nullptr;

test/ConstExtraction/ExtractResultBuilders.swift

+19-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public enum FooBuilder {
5757
public static func buildBlock(_ components: Component...) -> Component {
5858
return components.flatMap { $0 }
5959
}
60-
60+
6161
public static func buildLimitedAvailability(_ component: Component) -> Component {
6262
return component
6363
}
@@ -340,6 +340,9 @@ public struct MyFooProviderInferred: FooProvider {
340340
// CHECK-NEXT: ]
341341
// CHECK-NEXT: }
342342
// CHECK-NEXT: }
343+
// CHECK-NEXT: },
344+
// CHECK-NEXT: {
345+
// CHECK-NEXT: "element": {}
343346
// CHECK-NEXT: }
344347
// CHECK-NEXT: ],
345348
// CHECK-NEXT: "elseElements": [
@@ -360,6 +363,9 @@ public struct MyFooProviderInferred: FooProvider {
360363
// CHECK-NEXT: ]
361364
// CHECK-NEXT: }
362365
// CHECK-NEXT: }
366+
// CHECK-NEXT: },
367+
// CHECK-NEXT: {
368+
// CHECK-NEXT: "element": {}
363369
// CHECK-NEXT: }
364370
// CHECK-NEXT: ],
365371
// CHECK-NEXT: "elseElements": [
@@ -378,6 +384,9 @@ public struct MyFooProviderInferred: FooProvider {
378384
// CHECK-NEXT: ]
379385
// CHECK-NEXT: }
380386
// CHECK-NEXT: }
387+
// CHECK-NEXT: },
388+
// CHECK-NEXT: {
389+
// CHECK-NEXT: "element": {}
381390
// CHECK-NEXT: }
382391
// CHECK-NEXT: ]
383392
// CHECK-NEXT: }
@@ -436,6 +445,9 @@ public struct MyFooProviderInferred: FooProvider {
436445
// CHECK-NEXT: ]
437446
// CHECK-NEXT: }
438447
// CHECK-NEXT: }
448+
// CHECK-NEXT: },
449+
// CHECK-NEXT: {
450+
// CHECK-NEXT: "element": {}
439451
// CHECK-NEXT: }
440452
// CHECK-NEXT: ],
441453
// CHECK-NEXT: "elseElements": []
@@ -499,6 +511,9 @@ public struct MyFooProviderInferred: FooProvider {
499511
// CHECK-NEXT: },
500512
// CHECK-NEXT: {
501513
// CHECK-NEXT: "element": {}
514+
// CHECK-NEXT: },
515+
// CHECK-NEXT: {
516+
// CHECK-NEXT: "element": {}
502517
// CHECK-NEXT: }
503518
// CHECK-NEXT: ],
504519
// CHECK-NEXT: "elseElements": [
@@ -517,6 +532,9 @@ public struct MyFooProviderInferred: FooProvider {
517532
// CHECK-NEXT: ]
518533
// CHECK-NEXT: }
519534
// CHECK-NEXT: }
535+
// CHECK-NEXT: },
536+
// CHECK-NEXT: {
537+
// CHECK-NEXT: "element": {}
520538
// CHECK-NEXT: }
521539
// CHECK-NEXT: ]
522540
// CHECK-NEXT: }

validation-test/Sema/result_builder_buildBlock_resolution.swift

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
// RUN: %target-typecheck-verify-swift
22
// RUN: %target-typecheck-verify-swift -I %t
33

4-
// This test verifies that `buildBlock` is type-checked together with enclosing context,
5-
// which means that it's not captured into separate variable but rather used directly and
6-
// contextual information can impact overload resolution.
4+
// ! - Based on the result builders proposal `buildBlock` shouldn't be type-checked together with `buildOptional`.
75

86
protocol ActionIdentifier: Hashable {
97
}
@@ -14,11 +12,11 @@ struct ActionLookup<Identifier: ActionIdentifier> {
1412

1513
@resultBuilder
1614
enum ActionLookupBuilder<Identifier: ActionIdentifier> { // expected-note 3{{'Identifier' previously declared here}}
17-
static func buildBlock<Identifier: ActionIdentifier>(_ components: [ActionLookup<Identifier>]...) -> ActionLookup<Identifier> { // expected-warning {{generic parameter 'Identifier' shadows generic parameter from outer scope with the same name; this is an error in the Swift 6 language mode}}
15+
static func buildBlock<Identifier: ActionIdentifier>(_ components: [ActionLookup<Identifier>]...) -> ActionLookup<Identifier> { // expected-warning {{generic parameter 'Identifier' shadows generic parameter from outer scope with the same name; this is an error in the Swift 6 language mode}} expected-note {{found this candidate}}
1816
fatalError()
1917
}
2018

21-
static func buildBlock<Identifier: ActionIdentifier>(_ components: [ActionLookup<Identifier>]...) -> [ActionLookup<Identifier>] { // expected-warning {{generic parameter 'Identifier' shadows generic parameter from outer scope with the same name; this is an error in the Swift 6 language mode}}
19+
static func buildBlock<Identifier: ActionIdentifier>(_ components: [ActionLookup<Identifier>]...) -> [ActionLookup<Identifier>] { // expected-warning {{generic parameter 'Identifier' shadows generic parameter from outer scope with the same name; this is an error in the Swift 6 language mode}} expected-note {{found this candidate}}
2220
[]
2321
}
2422

@@ -43,7 +41,8 @@ enum ActionType: String, ActionIdentifier, CaseIterable {
4341
ActionTypeLookup(
4442
.download
4543
)
46-
if true { // If condition is needed to make sure that `buildOptional` affects `buildBlock` resolution.
44+
if true { // If condition without else is needed to make sure that `buildOptional` affects `buildBlock` resolution.
45+
// expected-error@-1 {{ambiguous use of 'buildBlock'}}
4746
ActionTypeLookup(
4847
.upload
4948
)

0 commit comments

Comments
 (0)