The following code compiles successfully and the program prints A
.
struct StringWrapper {
let string: String
}
extension StringWrapper: ExpressibleByStringInterpolation {
public init(stringLiteral: String) {
self.init(string: stringLiteral)
}
public init(stringInterpolation: StringWrapperInterpolation) {
self.init(string: stringInterpolation.content)
}
}
struct StringWrapperInterpolation: StringInterpolationProtocol {
var content: String
public init(literalCapacity: Int, interpolationCount: Int) {
content = ""
}
public mutating func appendLiteral(_ literal: String) {
content.append(literal)
}
public mutating func appendInterpolation(_ i: Int) {
content.append("<<\(i)>>")
}
}
@_functionBuilder
struct FB {
public static func buildBlock(_ content: StringWrapper...) -> String {
content.map(\.string).joined()
}
}
@FB
var functionBuilderValue: String {
StringWrapper("A")
}
print(functionBuilderValue)
If I replace the definition of functionBuilderValue
with the following snippet the program still compiles and prints A<<2>>
as expected.
let interpolatedInt: StringWrapper = "\(2)"
@FB
var functionBuilderValue: String {
StringWrapper("A")
interpolatedInt
}
If I replace the definition of functionBuilderValue
with the following snippet the program won't compile with the error Cannot convert value of type 'String' to expected argument type 'StringWrapper'
@FB
var functionBuilderValue: String {
StringWrapper("A")
"\(2)"
}
So, inside the body of a function builder, ExpressibleByStringInterpolation
doesn't work, which is unexpected. ExpressibleByStringLiteral
doesn't work either, but it's less of a problem because we can modify the function builder to take string literals.
Is there any technical problem blocking a fix for this?