mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[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.
This commit is contained in:
@@ -511,7 +511,8 @@ protected:
|
||||
|
||||
auto *ifBraceStmt = cast<BraceStmt>(ifStmt->getThenStmt());
|
||||
|
||||
std::tie(thenVarRef, unsupported) = transform(ifBraceStmt, thenBody);
|
||||
std::tie(thenVarRef, unsupported) =
|
||||
transform(ifBraceStmt, thenBody, /*isolateBuildBlock=*/true);
|
||||
if (unsupported) {
|
||||
recordUnsupported(*unsupported);
|
||||
return nullptr;
|
||||
@@ -546,7 +547,8 @@ protected:
|
||||
auto *elseBraceStmt = cast<BraceStmt>(elseStmt);
|
||||
SmallVector<ASTNode> elseBody;
|
||||
|
||||
std::tie(elseVarRef, unsupported) = transform(elseBraceStmt, elseBody);
|
||||
std::tie(elseVarRef, unsupported) = transform(
|
||||
elseBraceStmt, elseBody, /*isolateBuildBlock=*/true);
|
||||
if (unsupported) {
|
||||
recordUnsupported(*unsupported);
|
||||
return nullptr;
|
||||
|
||||
@@ -57,7 +57,7 @@ public enum FooBuilder {
|
||||
public static func buildBlock(_ components: Component...) -> Component {
|
||||
return components.flatMap { $0 }
|
||||
}
|
||||
|
||||
|
||||
public static func buildLimitedAvailability(_ component: Component) -> Component {
|
||||
return component
|
||||
}
|
||||
@@ -340,6 +340,9 @@ public struct MyFooProviderInferred: FooProvider {
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "element": {}
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "elseElements": [
|
||||
@@ -360,6 +363,9 @@ public struct MyFooProviderInferred: FooProvider {
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "element": {}
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "elseElements": [
|
||||
@@ -378,6 +384,9 @@ public struct MyFooProviderInferred: FooProvider {
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "element": {}
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
@@ -436,6 +445,9 @@ public struct MyFooProviderInferred: FooProvider {
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "element": {}
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "elseElements": []
|
||||
@@ -499,6 +511,9 @@ public struct MyFooProviderInferred: FooProvider {
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "element": {}
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "element": {}
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ],
|
||||
// CHECK-NEXT: "elseElements": [
|
||||
@@ -517,6 +532,9 @@ public struct MyFooProviderInferred: FooProvider {
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: {
|
||||
// CHECK-NEXT: "element": {}
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: ]
|
||||
// CHECK-NEXT: }
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
// RUN: %target-typecheck-verify-swift -I %t
|
||||
|
||||
// This test verifies that `buildBlock` is type-checked together with enclosing context,
|
||||
// which means that it's not captured into separate variable but rather used directly and
|
||||
// contextual information can impact overload resolution.
|
||||
// ! - Based on the result builders proposal `buildBlock` shouldn't be type-checked together with `buildOptional`.
|
||||
|
||||
protocol ActionIdentifier: Hashable {
|
||||
}
|
||||
@@ -14,11 +12,11 @@ struct ActionLookup<Identifier: ActionIdentifier> {
|
||||
|
||||
@resultBuilder
|
||||
enum ActionLookupBuilder<Identifier: ActionIdentifier> { // expected-note 3{{'Identifier' previously declared here}}
|
||||
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}}
|
||||
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}}
|
||||
fatalError()
|
||||
}
|
||||
|
||||
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}}
|
||||
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}}
|
||||
[]
|
||||
}
|
||||
|
||||
@@ -43,7 +41,8 @@ enum ActionType: String, ActionIdentifier, CaseIterable {
|
||||
ActionTypeLookup(
|
||||
.download
|
||||
)
|
||||
if true { // If condition is needed to make sure that `buildOptional` affects `buildBlock` resolution.
|
||||
if true { // If condition without else is needed to make sure that `buildOptional` affects `buildBlock` resolution.
|
||||
// expected-error@-1 {{ambiguous use of 'buildBlock'}}
|
||||
ActionTypeLookup(
|
||||
.upload
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user