Oh nice find/hack! I was just struggling with this last night.
Weirdly it worked when I wrote out the steps manually:
@resultBuilder public enum TupleBuilder {
public static func buildPartialBlock<T>(first: T) -> (T) {
return first
}
public static func buildPartialBlock<each A, B>(accumulated: (repeat each A), next: B) -> (repeat each A, B) {
return (repeat each accumulated, next)
}
}
func builder<each A>(@TupleBuilder content: ()->(repeat each A)) -> (repeat each A) {
return content()
}
func testManual() -> (String, Int, String, String) {
let a = TupleBuilder.buildPartialBlock(first: "a")
let b = TupleBuilder.buildPartialBlock(accumulated: a, next: 2)
let c = TupleBuilder.buildPartialBlock(accumulated: b, next: "b")
return TupleBuilder.buildPartialBlock(accumulated: c, next: "c")
}
// Cannot convert return expression of type '(((String, Int), String), String)' to return type '(String, Int, String, String)'
func testBuilder() -> (String, Int, String, String) {
return builder {
""
1
""
""
}
}
It took me writing this out (and double-checking the original proposal) to realize my buildPartialBlock was probably correct. This is my first experience with Parameter Packs, so I was driving myself crazy trying to rearrange the syntax.
It seems like maybe the generated code isn’t being type-checked/having its types resolved in the same way as hand-written code. It seems like the type structure of parameters packs is terrifyingly ~vague~ flexible, because all of these are valid:
func testManual() -> ((String, Int, String), String) {
let a = TupleBuilder.buildPartialBlock(first: "a")
let b = TupleBuilder.buildPartialBlock(accumulated: a, next: 2)
let c = TupleBuilder.buildPartialBlock(accumulated: b, next: "b")
return TupleBuilder.buildPartialBlock(accumulated: c, next: "c")
}
let tuplized: (String) = TupleBuilder.buildPartialBlock(first: "a")
let standalone: String = TupleBuilder.buildPartialBlock(first: "a")
let detuplized: String = TupleBuilder.buildPartialBlock(first: ("a"))
Maybe there’s an issue/bug in the result builder type checking casusing it to not emit all possible options for parameter packs?