[Accepted] SE-0389: Attached Macros

Hi folks,

The review for SE-0389: Attached Macros ran from February 16 to March 2. The language workgroup has decided to accept the proposal.

Feedback on the proposal was light but positive. Two questions were raised during the review that the workgroup gave additional consideration.

  1. The first question was around whether a synthesized memberwise init should be suppressed if a macro generates its own init into the type declaration to which it is attached. The workgroup concluded that the synthesized init should be suppressed in this case, just as it would be if the author had written the initializer by hand. As a general principle, the workgroup believes that the user should expect the same behavior from the compiler when using macros as they would see if they manually substituted the expanded code into their source file.

    The workgroup also recognizes that it is desirable to have better control over memberwise initializers as a general feature, so improvements in this space can be made independently of this proposal (but such future work could be implemented using macros).

  2. The second question asked whether attached macros should provide a way to specify generated names that are simultaneously prefixed and suffixed rather than just one of those choices. Such names can be produced using arbitrary, so the lack of a more specific feature does not make anything impossible—it merely omits a potential compiler optimization. Furthermore, more complex name generation schemes would likely need linguistic transformations to produce names that meet Swift API naming guidelines that are beyond what a combined prefixed/suffixed could supply.

    Therefore, the language workgroup does not feel that the additional complexity is warranted at this time. If either simultaneous prefix/suffix concatenation or more specific name generation schemes are found to be needed in the future, they can be proposed as additive changes.

Thank you to all who participated in the review!

—Tony Allevato, review manager

23 Likes

I’m sorry if this was covered in the proposal but I have a question about property wrappers and macros attached to function declarations. Assuming a function:

@MyMacro
func f(@LocalWrapper arg: Int) {}

What would the macro take as input? Would it take the untransformed declaration and just see the @LocalWrapper? I wouldn’t think so because the macro has no knowledge of that property wrapper so it can perform the property-wrapper expansion on its own. But what about the case of an API-level property wrapper?

@MyMacro
func f(@SwiftUI.Binding arg: Int) {}

This property wrapper is supposed to generate a thunk. So will the macro get only the normal method, or will it also receive the thunk (and how)?

This might be a dumb question, but I just brought this up because the experimental macro toolchain seemed to emit errors about thunks when using API-Level wrappers.

I had thought the answer would be the same as that when there is an expression macro in the argument: whether the source-level transformations are applied “outside-in” or “inside-out” should be consistent throughout. Naively, it would see that this should respect the precedent when we compose @WrapperA @WrapperB.

Sorry if this was covered in proposal, I have one question regarding type-inference. Mainly would macro get inferred type data for variables where type isn't explicitly mentioned? i.e for the following declaration:

@MyMacro
struct MyStruct {
    let myVar = 0
}

will the MyMacro have any way to determine type of myVar?

Not yet; macros currently only have access to the syntax information present in the source file.