makeUniqueName() produces tokens that cannot be used as closure arguments
Description
If I attempt to label closure arguments during macro expansion:
let arg0 = context.makeUniqueName("")
return """
{ \(arg0) in
...
}
"""
The compiler complains:
🛑 Inferred projection type 'Int' is not a property wrapper 🛑 Inferred projection type '() -> Int' is not a property wrapper
This means I can't reliably produce closure argument names, which is problematic if my macro expansion generates a closure and the macro is being used inside another closure:
@Test func foo() {
let x = [2, 4, 6]
x.forEach {
#expect($0 % 2 == 0) // 🛑 Anonymous closure arguments cannot be used inside
// a closure that has explicit arguments; did you mean '$0'?
}
}
Steps to Reproduce
See above.
See also https://github.com/apple/swift/pull/68475
~~I can repro with swift-DEVELOPMENT-SNAPSHOT-2023-10-02-a-osx, which I think means #68475 isn't a complete fix.~~ My mistake, I was using a different toolchain.
Having a day here… :) The issue with the spurious error is fixed, but I still can't use makeUniqueName() to generate my labels.
Tracked in Apple’s issue tracker as rdar://116402749
Reduced reproducer
public struct StringifyMacro: ExpressionMacro {
public static func expansion(
of node: some FreestandingMacroExpansionSyntax,
in context: some MacroExpansionContext
) -> ExprSyntax {
guard let argument = node.argumentList.first?.expression else {
fatalError("compiler bug: the macro does not have any arguments")
}
let arg0 = context.makeUniqueName("")
return """
{ \(arg0) in
return \(argument)
}(1)
"""
}
}
Usage
_ = #stringify(a + b)
Expands to the following, which doesn’t compile
_ = { $s17mac_adsfjlkClient33_E5FD3D533106409A33F51D71F9BB5B8CLl9stringifyfMf_7__localfMu_ in
return a + b
}(1)