Circular reference when combining attached peer and extension macros

Not sure if this is a bug or a feature/limit of Swift,

but I'm currently getting different behaviour between manually written code and the code generated by my Swift Macro.

Consider the below macro and it's expanded code:

protocol SomeProtocol { }

// < expanded >
struct SomeTypeThatConforms: SomeProtocol {
    static func makeAConformingThing() -> SomeTypeThatConforms { .init() }

extension SomeProtocol {
    typealias MyAlias = SomeTypeThatConforms
// < / expanded >

Where @MyMacro expands and implements the protocol in to the struct type with a peer macro, then with an extension macro creates a typealias to the struct within the protocol.

When expanding that code the the compiler fails with an error of circular reference, which makes sense because of course:


can then infinitely reference itself...

SomeProtocol.MyAlias.MyAlias.MyAlias.MyAlias.MyAlias.MyAlias // ...

because all SomeTypeThatConforms are SomeProtocols which then have MyAlias on them.


When I manually type out the above in Xcode (without the @MyMacro of course) then the compiler works fine and allows the static referencing for me to call the static func like so:


It seems odd that:

  1. this infinite recursion is allowed
  2. depending on whether the code is manually written or generated with a macro it has different effects

Is anyone able to provide any details of this?
Maybe there's something really obvious going on here with either macros or Swift that I'm just not seeing?