I am proposing to relax the use of compiler-generated $-prefixed identifiers in closures, specifically since the current restriction prevents the use of MacroExpansionContext.makeUniqueName(_:) as the identifier of a closure argument when expanding a macro.
Introduction
The prefix $ is currently reserved for compiler-generated identifiers, the Swift grammar explicitly states the use of $-prefixed identifiers as follows,
implicit-parameter-name → $ decimal-digits
property-wrapper-projection → $ identifier-characters
In practice, the compiler does not prohibit the use of $-prefixed identifiers in other context except for the use of $ decimal-digits outside of the closure scope and the use of $ identifier-characters as explicit closure argument names inside the closure scope.
Motivation
When expanding a macro, every invocation of MacroExpansionContext.makeUniqueName(_:) will return a name unique in the current macro context, preventing naming conflicts when the macro introduces new identifiers. Because these unique names are also prefixed with $ as they are generated by the compiler, as a result, the compiler hinders the use of these unique names as closure argument names in macro expansion, (example courtesy of @grynspan)
let arg0 = context.makeUniqueName("")
return """
{ \(arg0) in
...
}
"""
The compiler will report the following errors from the expanded source,
Inferred projection type 'Int' is not a property wrapper
Inferred projection type '() -> Int' is not a property wrapper
because the expanded source will look something like this,
{ $s<SOME_MINGLED_NAME> in
...
}
that the compiler interprets $s<SOME_MINGLED_NAME> as a property-wrapper-projection instead of an explicit closure argument.
Proposed Solution
The restriction on the use of $ identifier-characters as explicit closure argument names should be lifted. Such lift will not introduce any naming conflict since $ decimal-digits is still exclusively reserved for implicit closure argument names, while enabling macro authors working with closures to improve macro hygiene through the use of MacroExpansionContext.makeUniqueName(_:).