# Allow attached macros to not suppress the memberwise initializer

**URL:** <https://forums.swift.org/t/allow-attached-macros-to-not-suppress-the-memberwise-initializer/65392>\
**Category:** Discussion\
**Tags:** attached-macros\
**Created:** [June 7, 2023, 6:23am UTC](https://forums.swift.org/t/allow-attached-macros-to-not-suppress-the-memberwise-initializer/65392 "2023-06-07T06:23:30Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![gwendal.roue](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gwendal.roue/32/13992_2.png) [@gwendal.roue](https://forums.swift.org/u/gwendal.roue)\
**Post date:** [June 7, 2023, 6:23am UTC](https://forums.swift.org/t/allow-attached-macros-to-not-suppress-the-memberwise-initializer/65392/1 "2023-06-07T06:23:30Z")

</div>

Continuing the discussion from [SE-0389: Attached Macros](https://forums.swift.org/t/se-0389-attached-macros/63165/19):

> [@SE-0389: Attached Macros](https://forums.swift.org/t/se-0389-attached-macros/63165/19):
>
> I feel like that discussion settled on it being correct to disable synthesis of the memberwise init when a macro creates an `init`" (because it follows the rules as-if you'd written the code without the macro), but that we might consider some kind of `@doesNotSuppressMemberwiseInit` attribute separately.

Hello, well I'm very happy that macros have shipped, and I can't wait for GRDB to remove its own boilerplate code so that it doesn't look too bad in front of SwiftData.

And I'd really like to _add_ initializers, but not to suppress the default memberwise one (just like `Codable` does). In the specific case of GRDB, removing the Codable requirement for database records would immensely help performance (see [this discussion](https://github.com/groue/GRDB.swift/discussions/1323#discussioncomment-6108687)).

@Douglas_Gregor, do you think I should just create a GitHub issue, or that this would require a evolution process of its own?

---

<div class="post-metadata">

**Author:** ![gwendal.roue](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gwendal.roue/32/13992_2.png) [@gwendal.roue](https://forums.swift.org/u/gwendal.roue)\
**Post date:** [June 7, 2023, 4:45pm UTC](https://forums.swift.org/t/allow-attached-macros-to-not-suppress-the-memberwise-initializer/65392/2 "2023-06-07T16:45:39Z")

</div>

> [@SE-0389: Attached Macros](https://forums.swift.org/t/se-0389-attached-macros/63165/19):
>
> we might consider some kind of `@doesNotSuppressMemberwiseInit` attribute separately

In my understanding, this new attribute would decorate initializers. This would work.

Another option would be to make `@attached` macros able to wrap their added members in an extension (since initializers declared in extensions do not remove the memberwise init).

Actually, it might be interesting for macros that combine the `member` and `conformance` roles to be able to wrap the new members inside the added conformances.

So instead of having:

```swift
@MyMacro
struct MyStruct {
    // Generated by the `member` role inside MyStruct
    func myConformance() { }
}

// Generated by the `conformance` role as a peer to MyStruct
extension MyStruct: MyProtocol { }

```

We'd have:

```swift
@MyMacro
struct MyStruct { }

// Generated by the `member + conformance` roles
extension MyStruct: MyProtocol {
    func myConformance() { }
}

```

(I can see how difficult it is to build this on top of the existing `ConformanceMacro` and `MemberMacro` protocols.)

Yet this would improve the legibility of the generated code, and that's important. And I know [one well-appreciated pitch](https://forums.swift.org/t/pre-pitch-explicit-protocol-fulfilment-with-the-conformance-keyword/60246) that would profit for this kind of generation (conformance extensions that wrap the matching requirements). And several members of the steering group have expressed in this pitch that they _love_ to wrap protocol requirements in dedicated extensions :-)

Now this would be a rather big change… and it is not my interest to wait too long. Destroying the memberwise init is not acceptable for GRDB users. I would be so disappointed to see the lib excluded from the macros game for months, years, just because of this "little" issue that was glossed over during the review of attached macros. 😖

Attempting at generating the memberwise init myself looks like fighting the language, spilling a lot of energy, and just an opportunity to create bugs or odd mismatches.

What can I do?

---

<div class="post-metadata">

**Author:** ![hborla](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/hborla/32/27563_2.png) [@hborla](https://forums.swift.org/u/hborla)\
**Post date:** [June 7, 2023, 10:21pm UTC](https://forums.swift.org/t/allow-attached-macros-to-not-suppress-the-memberwise-initializer/65392/3 "2023-06-07T22:21:59Z")

</div>

> [@gwendal.roue](#):
>
> Actually, it might be interesting for macros that combine the `member` and `conformance` roles to be able to wrap the new members inside the added conformances.

I think this is an interesting suggestion. It made me wonder whether the `conformance` macro role should instead be an `extension` macro role, based on two observations:

1. The `conformance` macro role is not useful on its own; it's pretty much always used in combination with `member`.
2. The extension capability that the `conformance` macro role has today is useful independent of conformances.

We deliberately don't want macros to be able to add arbitrary extensions as peers due to the way extension binding has to work, but conformance macros are a restricted form of this because they specifically add an extension to the annotated type, so we can bind the extension immediately after macro expansion. This seems more generally useful, and I could imagine the `ConformanceMacro` protocol being generalized to `ExtensionMacro` with 2 requirements: the existing requirement to gather the declared conformance and `where` clause (which could each be optional), and another to gather the members that are added to the extension. This would solve your initializer problem, because it would allow you to generate initializers in an extension which would then not suppress the compiler-synthesized initializer...

---

<div class="post-metadata">

**Author:** ![Slava\_Pestov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/slava_pestov/32/30204_2.png) [@Slava\_Pestov](https://forums.swift.org/u/Slava_Pestov)\
**Post date:** [June 7, 2023, 10:37pm UTC](https://forums.swift.org/t/allow-attached-macros-to-not-suppress-the-memberwise-initializer/65392/4 "2023-06-07T22:37:53Z")

</div>

> [@gwendal.roue](#):
>
> Attempting at generating the memberwise init myself looks like fighting the language, spilling a lot of energy, and just an opportunity to create bugs or odd mismatches.

Perhaps reworking the memberwise init into a standard macro would be better than adding a special attribute; we have too many of those already. Then the current behavior of the memberwise init getting synthesized by default would just become a special case where the compiler invokes the macro.

---

<div class="post-metadata">

**Author:** ![gwendal.roue](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/gwendal.roue/32/13992_2.png) [@gwendal.roue](https://forums.swift.org/u/gwendal.roue)\
**Post date:** [June 8, 2023, 3:58am UTC](https://forums.swift.org/t/allow-attached-macros-to-not-suppress-the-memberwise-initializer/65392/5 "2023-06-08T03:58:49Z")

</div>

... and other macros could invoque it as well, is that your idea? This should work at first glance.

Now, there is evolution pressure on the memberwise init: it is regularly the topic of feature requests, evolution discussions, or pitches. Strictly locking the memberwise init inside the feature set of macros would seriously limit its evolution space, don't you think? For example, some "issues" listed in this old thread [State of the Memberwise Initializer](https://forums.swift.org/t/state-of-the-memberwise-initializer/17168) are still relevant (access control and classes).

The memberwise initializer is one of the most crucial user-facing features of the language. Its ergonomics are paramount, and should be enhanced, not restricted. I understand that macros were introduced in order to address the need and desire to send inner compiler features to userland (among other reasons). But it's important to protect a few key areas - including the memberwise init IMHO. That's the idea I suggest the Language Steering Group to contemplate.
