[Pitch] Declaration macros

I think that's fine, yes, although the form of AttachedDeclarationExpansion currently means you won't be able to change anything about the case.

As in the expression-macros proposal, macro expansion is outside-in, so @outerMacro would get expanded first. It would see the unexpanded @innerMacro on var i.

No, it will not.

Maybe? Right now, we don't have an easy way for a macro applied to a type to add accessors to its members, but this seems like something that could fit into the model. @hborla has been thinking about this a bit and might want to weigh in.

You're absolutely right. I should incorporate this additional argument into the proposal test, thanks!

Yeah, the ability to replace a function body does feel a bit different than the rest of the proposal. It's a really useful capability, but perhaps it should be split out into a separate proposal. Perhaps we should see how many of our interesting use cases depend on it.

Sure, the macro could look into the function declaration's parameter list to find the parameter, if it's there, and use it. However, it might be hard to precisely determine that the function parameter has the precise type you want, without an extension to the macro expansion context that provides type information.

Inserted code will be type-checked in the same way that the originally-written code is type-checked, so you can return from a Void function, or return nil from an optional-returning function, and it's fine.

This seems more like constant initialization than macros. Perhaps we could find a way to do this with macros if they were able to add binary blobs to the resulting object file, which is something we could permit by adding more API to MacroExpansionContext. This could also be useful for implementing something like the C23 or Rust #embed.

Right, this area is dicey, because macro expansion will occur as part of type checking. This is much of the (implementation) reason why declaration macros can only have specific, prescribed effects, and we declare them in the macro itself, so we can make sure that expanding a macro cannot invalidate a previous result.

Yes. Effectively, .freestanding can only have peers, since there is no way for it to have members.

We could do that. I'm not at all... attached... to the design of these attribute arguments.

I was thinking it would be okay to overpromise in a macro declaration. In the option-set example, we shouldn't require the macro to define a rawValue if the user already wrote one, but that's the only reason I'd thought of for allowing a macro not to introduce a declaration that it said it might.

Yeah, this feels a little sketchy. We could have accessors be a separate thing entirely, which might feel cleaner.

Yes, I should add an example here, because @Alejandro_Martinez had a similar question.

Hmm. I was intending AttachedDeclarationExpansion.functionBody to be used for this purpose. Is that not enough, if it can replace the body?

Doug

3 Likes