Function Builder not working when only one value?

I have a functionBuilder


@_functionBuilder
struct MyBuilder {
    static func buildBlock(_ numbers: Int...) -> Int {
        var result = 0
        for number in numbers {
            result += number * 2
        }
        return result
    }
}


Function


func myFunc(@MyBuilder builder: () -> Int) -> Int {
    builder()
}


Use


let a = myFunc {
    10
    20
}
print(a) // print 60 is work!


but


let b = myFunc {
    10
}
print(b) // print 10?


Why is b not 20?

I try add other buildBlock


static func buildBlock(number: Int) -> Int {
    return number * 2
}


But not working 😟

Any idea?

In the second case, buildBlock is not even called (test with a print inside)

Seems effectively to have a problem with single value.


tried this:


@_functionBuilder
struct MyBuilder {
    static func buildBlock(_ numbers: Int...) -> Int {
        print("Call")
        var result = 0
        for number in numbers {
            result += number * 2
        }
        return result
    }
    static func buildBlock(_ numbers: String...) -> Int {
        print("Call strings")
        var result = 0
        for number in numbers {
            result += Int(number)! * 2
        }
        return result
    }
}

func myFunc(@MyBuilder builder: () -> Int) -> Int {
    builder()
}

let a = myFunc {
    10
    20
}
print(a) // print 60 is work!

let b = myFunc {
    10
}
print(b) // print 10?

let c = myFunc {
    "10"
    "20"
}
print(c)

c is OK:

Call

60

10

Call strings

60


Now, I add


let d = myFunc {
    "10"
}
print(d)


I get a playground error:

Cannot convert value of type 'String' to closure result type 'Int'


Could be a bug in this version of functionBuilder, unable to interpret correctly the closures.


Did you ask on Swift.org ?

Hi, have you got a solution on this? I got this problems too

It seems that builder does not correctly handle a single parameter.

I guess it comes from the way TupleBuilder works (see proposal #1046)

h ttps://github.com/apple/swift-evolution/pull/1046/files/9992cf3c11c2d5e0ea20bee98657d93902d5b174#diff-574288be49e1083468cae7dfa3d37a30


@TupleBuilder
func build() -> (Int, Int, Int) {
  1
  2
  3
}
// This code is interpreted exactly as if it were this code:
func build() -> (Int, Int, Int) {
  let _a = 1
  let _b = 2
  let _c = 3
  return TupleBuilder.buildBlock(_a, _b, _c)
}


Just as if building tuple with a single element (which is now forbidden) caused the problem.


Solution should be to either:

- report a bug to Apple

- go to Swift.org forum and ask


Instructive discussions there, such as

h ttps://forums.swift.org/t/function-builders/25167/150


Good luck

Function Builder not working when only one value?
 
 
Q