Default argument values for Swift macros?

I'm trying to create macro that has an optional closure argument. I'll simplify.

The interface looks like this:

@freestanding(expression)
public macro myMacro(closure: (()->())? = nil) -> Void = #externalMacro(module: "MyMacrosImplementation", type: "MyMacro")

My macro unit tests work as expected, with both the 0 argument and 1 argument test cases. But tests in actual code are not working as expected. For example, when I do:

#myMacro(closure: {
print("Hello, World")
})

it behaves as if no closure argument was passed. And Xcode isn't allowing me to see the expansion.


Update: I've figured this out. It had to do with the way I was testing. I was using the macro from top level code and that produced odd behavior. Here's test code that works as expected. TestMacroArgs2.zip - Google Drive

Since what macro code can see is AST (it's true for macro's arguments too), it doesn't have built-in support for argument default value. You need to support it in argument parsing code in your macro. If an argument isn't specified and has a default value, your macro use that value. Caveat: with this approach, the default value specified in macro interface declaration is just a place holder and not really used.

2 Likes