# resultBuilder buildOptional issue

**URL:** <https://forums.swift.org/t/resultbuilder-buildoptional-issue/62497>\
**Category:** Using Swift\
**Tags:** result-builder\
**Created:** [January 10, 2023, 4:47pm UTC](https://forums.swift.org/t/resultbuilder-buildoptional-issue/62497 "2023-01-10T16:47:29Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kyle-Ye](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kyle-ye/32/19686_2.png) [@Kyle-Ye](https://forums.swift.org/u/Kyle-Ye)\
**Post date:** [January 10, 2023, 4:47pm UTC](https://forums.swift.org/t/resultbuilder-buildoptional-issue/62497/1 "2023-01-10T16:47:29Z")

</div>

Normally, the following code cannot be compiled.

```swift
let a = 3
if let b = a { // ❌Error: Initializer for conditional binding must have Optional type, not 'Int'
...
}

```

But if we define a resultBuilder and implement buildOptional method, similar code can be compiled.

```swift
@resultBuilder
enum XBuilder {
    static func buildBlock(_: Int...) -> Int {
        0
    }

    static func buildOptional(_: Int?) -> Int {
        1
    }
}

func test(@XBuilder content: () -> Int) -> Int {
    content()
}

let a = 3
_ = test {
    if let b = a {
        b
    }
}

```

Is this the expected behavior of resultBuilder or a bug? Can anyone help me explain this grammar?

> Test it on swift-5.6 and swift-5.7. (Unlikely to be related to SE0345)

> **Original Context**
>
> Found this strange grammar when coding with SwiftUI.
> 
> ```swift
> struct ContentView: View {
> @State var enable = true
> 
> var body: some View {
> VStack {
> if let e = enable { // ✅ Working
> Text("")
> .onAppear {
> test1() // ❌ Not working
> test2 { // ✅ Working
> if let e = $enable {
> Text("1")
> }
> }
> }
> }
> }
> }
> 
> @ViewBuilder
> func test1() -> some View{
> if let e = $enable {
> Text("")
> }
> }
>     
> func test2(@ViewBuilder content: () -> some View) -> some View{
> content()
> }
> }
> 
> ```

---

<div class="post-metadata">

**Author:** ![Kyle-Ye](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kyle-ye/32/19686_2.png) [@Kyle-Ye](https://forums.swift.org/u/Kyle-Ye)\
**Post date:** [May 8, 2023, 5:00pm UTC](https://forums.swift.org/t/resultbuilder-buildoptional-issue/62497/2 "2023-05-08T17:00:28Z")

</div>

The bug is confirmed to be fixed on Swift 5.8 with an error message "Initializer for conditional binding must have Optional type, not 'Int'" like the normal code.

Thanks you for the rewrite of ResultBuilder @xedin

See the post for more detail: [Improved Result Builder Implementation in Swift 5.8 - #13 by xedin](https://forums.swift.org/t/improved-result-builder-implementation-in-swift-5-8/63192/13)

And does it possible to add such code to the test case for ResultBuilder in case the bug regress on later Swift version?

---

<div class="post-metadata">

**Author:** ![xedin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xedin/32/309_2.png) [@xedin](https://forums.swift.org/u/xedin)\
**Post date:** [May 8, 2023, 5:04pm UTC](https://forums.swift.org/t/resultbuilder-buildoptional-issue/62497/3 "2023-05-08T17:04:44Z")

</div>

> And does it possible to add such code to the test case for ResultBuilder in case the bug regress on later Swift version?

Yeah, we do have test cases in the suite that make sure that we catch regressions with optional bindings in the future.

---

<div class="post-metadata">

**Author:** ![Kyle-Ye](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kyle-ye/32/19686_2.png) [@Kyle-Ye](https://forums.swift.org/u/Kyle-Ye)\
**Post date:** [May 8, 2023, 5:29pm UTC](https://forums.swift.org/t/resultbuilder-buildoptional-issue/62497/4 "2023-05-08T17:29:57Z")

</div>

Could you point which test case / test file covers this behavior?

Just do a quick search with the following 2 filters on Swift's main branch. I did not get the expected test case for it.

[Filter 1: expected-error{{](https://github.com/search?q=repo:apple/swift+//+expected-error%7B%7BInitializer+for+conditional+binding+must+have+Optional+type+language:Swift&type=code&l=Swift)

```swift
// Expected test case

@resultBuilder
enum XBuilder {
    static func buildBlock(_: Int...) -> Int {
        0
    }

    static func buildOptional(_: Int?) -> Int {
        1
    }
}

func test(@XBuilder content: () -> Int) -> Int {
    content()
}

let a = 3
_ = test {
    if let b = a { //expected-error{{initializer for conditional binding must have Optional type, not 'Int'}}
        b
    }
}

```

---

<div class="post-metadata">

**Author:** ![xedin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xedin/32/309_2.png) [@xedin](https://forums.swift.org/u/xedin)\
**Post date:** [May 8, 2023, 5:32pm UTC](https://forums.swift.org/t/resultbuilder-buildoptional-issue/62497/5 "2023-05-08T17:32:27Z")

</div>

`validation-test/Sema/SwiftUI/mixed_swiftui_and_multistatement_closures.swift`

---

<div class="post-metadata">

**Author:** ![Kyle-Ye](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kyle-ye/32/19686_2.png) [@Kyle-Ye](https://forums.swift.org/u/Kyle-Ye)\
**Post date:** [May 8, 2023, 5:38pm UTC](https://forums.swift.org/t/resultbuilder-buildoptional-issue/62497/6 "2023-05-08T17:38:59Z")

</div>

[New Filter: expected-error {{](https://github.com/search?q=repo:apple/swift+//+expected-error+%7B%7Binitializer+for+conditional+binding+must+have+Optional+type+language:Swift&type=code&l=Swift)

Got it. I missed the space in it. Looks like both `expected-error{{` and `expected-error {{` are supported format for the test tool. I just searched the first one while ignored the second case 🤣

Thank you for your reply.

---

<div class="post-metadata">

**Author:** ![xedin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/xedin/32/309_2.png) [@xedin](https://forums.swift.org/u/xedin)\
**Post date:** [May 8, 2023, 5:39pm UTC](https://forums.swift.org/t/resultbuilder-buildoptional-issue/62497/7 "2023-05-08T17:39:31Z")

</div>

No problem!
