cc @Douglas_Gregor, I'm 90% sure the single expression worked in Xcode 11.3.x if we added wrapIntoAnyP
manually as it previously had no support for buildExpression
. Now in Xcode 11.4 non of the single expressions seem to work. The compiler does not want to pick up the expression convert it into AnyP
and then build the block from it.
struct AnyP<T>: P {
typealias C = T
let value: Any
}
protocol P {
associatedtype C
}
extension P {
func wrapIntoAnyP() -> AnyP<C> {
AnyP(value: self)
}
}
extension String: P {
typealias C = Int
}
extension Bool: P {
typealias C = Int
}
extension Optional: P where Wrapped: P {
typealias C = Wrapped.C
}
@_functionBuilder
enum Builder {
static func buildExpression<T, C>(
_ content: T
) -> AnyP<C> where T: P, T.C == C {
content.wrapIntoAnyP()
}
static func buildIf<T, C>(
_ content: T?
) -> AnyP<C> where T: P, T.C == C {
content.wrapIntoAnyP()
}
static func buildBlock<C>(
_ components: AnyP<C>...
) -> [AnyP<C>] {
components
}
}
func foo<T>(@Builder test: () -> [T]) where T: P {}
// OKAY
foo {
true
"swift"
}
foo { // error: Generic parameter 'T' could not be inferred
true // error: Cannot convert value of type 'Bool' to closure result type '[T]'
}