[Update] Restrictions on Arbitrary Names at Global Scope in SE-0389 and SE-0397

Hi folks,

After the acceptance of SE-0389 and SE-0397, further implementation work showed that allowing macros to introduce arbitrary names at global scope is fundamentally prone to creating cycles during type resolution. When performing unqualified name lookup, the compiler must expand all macros that produce arbitrary names, but such a macro may also have arguments that must be type-checked prior to expansion, and doing so would require expanding the very same macro.

This limitation is not a minor obstacle to overcome but a characteristic of the design of Swift macros, so the Language Steering Group does not feel that a review of an amendment to the proposal would change the outcome. Therefore, we have updated SE-0389 and SE-0397 to add the restriction that peer macros and freestanding macros cannot introduce arbitrary names at global scope.

Note that this restriction only applies to arbitrary names; peer macros can still introduce declarations into global scope with named, prefixed, suffixed, or overloaded names, and freestanding macros can still introduce named declarations into global scope.

—Tony, on behalf of the Language Steering Group

12 Likes

Just to make sure I understand, a peer macro not at global scope can still use arbitrary?

2 Likes

That's correct.

2 Likes

That sounds like a great improvement.
However, I am struggling with introducing prefixed and suffixed macro at the same time.

There is an example where I was trying to do it by using two sequential macro: Peer macros on a protocol - #11 by blindspotbounty but that sounds like a hack.
Furthermore, it doesn't work due to compiler bug: Sequential peer macro (PeerMacro) is not taken in attention for compilation but conflicts with re-declarations (swift 5.9) · Issue #67506 · apple/swift · GitHub

Therefore, I was looking for some solution that is in place or probably in plans. I would expect something like names: prefixed(Prefix) & suffixed(Suffix) or names: prefixed(Prefix), suffixed(Suffix) that would include name: PrefixSomeNameSuffix.

Could you suggest if it is currently possible in some way, please?

UPD: other thing that used to be possible was related to arbitrary conformance: generating protocol by struct/class definition and make a conforming extension for it. Example is here: [Accepted] SE-0402: Generalize `conformance` macros as `extension` macros - #5 by blindspotbounty

Though it might be not very often cases for macro, they still might be valid.