# Peer macros on a protocol

**URL:** <https://forums.swift.org/t/peer-macros-on-a-protocol/65469>\
**Category:** Discussion\
**Tags:** macros, attached-macros\
**Created:** [June 9, 2023, 5:51pm UTC](https://forums.swift.org/t/peer-macros-on-a-protocol/65469 "2023-06-09T17:51:31Z")\
**Posts on this page:** 1\
**Showing post:** 11

<div class="post-metadata">

**Author:** ![blindspotbounty](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/blindspotbounty/32/44760_2.png) [@blindspotbounty](https://forums.swift.org/u/blindspotbounty)\
**Post date:** [July 25, 2023, 11:51am UTC](https://forums.swift.org/t/peer-macros-on-a-protocol/65469/11 "2023-07-25T11:51:24Z")

</div>

> [@Douglas\_Gregor](#):
>
> As noted above, we have `prefixed` and `suffixed` for names derived from the attached type. These were [documented in SE-0389](https://github.com/apple/swift-evolution/blob/main/proposals/0389-attached-macros.md#specifying-newly-introduced-names). The "arbitrary" restriction at global scope prevents us from having to expand macros every time, for every source file in a module, because every name lookup could conceivably find something there. It's a potentially serious compile-time performance problem, and was also the root of a number of bugs we found where seemingly-innocuous code would break with a "circular reference" diagnostic.

`arbitrary` indeed seems bad at global scope. However, I was looking if it is possible to make `prefixed` and `suffixed` name at the same time instead of previously arbitrary. For example:

```swift
@MyMacro
struct MyStruct {
...
}

```

which generates:

```swift
struct MyStruct {
...
    enum _Enum {}
    enum _Value {}
}

public typalias MyLibMyStructEnum = MyStruct._Enum
public typalias MyLibMyStructValue = MyStruct._Value
...

```

Currently, the following macro description doesn't allow that:

```swift
@attached(peer, names: prefixed(MyLib), suffixed(Value), suffixed(Enum))
public macro MyMacro() = #externalMacro(...)

```

with error:

```swift
error: declaration name 'MyLibMyStructValue' is not covered by macro 'MyMacro'
public typealias MyLibMyStructValue = MyStruct._Value

```

I can imagine that it is possible by making some ugly hacks like using two macros:

```swift
@attached(peer, names: suffixed(Value), suffixed(Enum))
public macro MyMacro() = #externalMacro(...)

```

which generates dummy structures:

```swift
@PrefixAndPublic
typalias MyStructEnum = MyStruct._Enum
@PrefixAndPublic
typalias MyStructValue = MyStruct._Value

```

and the second:

```swift
@attached(peer, names: prefixed(MyLib))
public macro PrefixAndPublic() = #externalMacro(...)

```

that adds public and prefixed declarations:

```swift
public typalias MyLibMyStructEnum = MyStruct._Enum
public typalias MyLibMyStructValue = MyStruct._Value

```

However, I was looking for some solutions that would be correct and pretty at the same time like:

```swift
@attached(peer, names: prefixed(MyLib) & suffixed(Value), prefixed(MyLib) & suffixed(Enum))
public macro MyMacro() = #externalMacro(...)

```

Maybe I miss something and someone could guide me to the right direction, please?

UPD: also put and issue related to sequential peer macro unfolding: [Sequential peer macro (PeerMacro) is not taken in attention for compilation but conflicts with re-declarations (swift 5.9) · Issue #67506 · apple/swift · GitHub](https://github.com/apple/swift/issues/67506)

---

_[View the full topic](https://forums.swift.org/t/peer-macros-on-a-protocol/65469)._
