[Returned for revision] SE-0539: Enable Macros to Grant `self` Access for Property Initializers

Hello, Swift community!

The review of SE-0539: Enable Macros to Grant self Access for Property Initializers ended on August 16th, 2026. The Language Steering Group has decided to return this proposal for revision.

The Language Steering Group agrees that this is a problem worth solving and that the proposed behavior could still be useful to some subset of macros in its current form. However, the review discussion exposed gaps in the proposed solution that we believe users of the feature would immediately bump into when trying to use it for many real-world use cases.

The most significant gap is how a macro that wanted to provide lazy-like semantics would obtain the type of the property to define its backing storage. The proposal text stated in its Detailed Design section that the macro would be called with information about the inferred type of the property, but there are insufficient details to explain how this would be communicated to the macro:

  • The only way the macro can receive the information through the interface it has today would be for the compiler to synthesize a type annotation on the original VarDeclSyntax node. However, SwiftSyntax trees always represent a view of the actual source code and do not have a way to directly represent implicit/synthesized nodes. This would make it impossible for a macro to distinguish between an inferred type and an explicitly provided type annotation, if it so wished.
  • Assuming the first problem is resolved, there needs to be a description of how the inferred type would be spelled to avoid ambiguity arising from different scopes where the macro might be expanded. For example, when .swiftinterface files are printed, they now emit names that fully-qualify each segment with a module selector; e.g., Swift::Unicode.Swift::UTF8.Swift::CodeUnit.

The proposed functionality also applies only to accessor macros. Some reviewers raised concerns about whether the feature should also be allowed for peer macros, since a peer macro would be required for macros that want to declare backing storage for a property. That property would also need either the inferred type or it would need access to the initializer expression (appropriately type-checked to respect usage of self) to pass it to an expression that would let it infer its type (e.g., a generic function that takes the expression as an autoclosure and returns nil).

Another gap involves init accessors. If an accessor macro generates an init accessor and wants to use the property's initializer expression in its implementation, then it must know which stored properties that the initializer expression references so that they can be declared in @storageRestrictions. Semantic information like this is not passed into macros, and it is not possible from the purely syntactic view of the expression to determine which identifiers refer to stored properties. The Language Steering Group recognizes that lazy semantics don't need this because the storage would not be initialized in an init accessor, but since this proposal is offering a more general solution for arbitrary macros, interactions between this feature and init accessors need to be considered more thoroughly.

Due to the complexity and open design space of these remaining issues, the Language Steering Group believes that the revisions would benefit from further discussion among the community. We encourage the proposal author to explore the issues further and bring revisions back for another pitch discussion before returning the proposal for another round of review.

Thank you to everyone who participated in the review!

—Tony Allevato
Review manager

8 Likes