Compilation issue for code generated by Swift Macro for Equatable

Swift compiler doesn't Synthesize Equatable and Hashable conformance for classes due to the complexity of class inheritance hierarchies. 0185-synthesize-equatable-hashable

However, there are still cases where the generated code is helpful especially for a root class. Therefore, I have tried to implement this using Swift Macro. However, I have encountered issues like below:

In short, I can generate necessary code below using macro, but it doesn't compile.

However, the same code will work if it's not generated from macro.

Could someone help here? Many thanks. @Douglas_Gregor

The macro code is below:

public struct Equatable: ConformanceMacro, MemberMacro {
    public static func expansion<Declaration: DeclGroupSyntax,
                                 Context: MacroExpansionContext>(of node: AttributeSyntax,
                                                                 providingConformancesOf declaration: Declaration,
                                                                 in context: Context) throws -> [(TypeSyntax, GenericWhereClauseSyntax?)] {
        guard [SwiftSyntax.SyntaxKind.classDecl, .actorDecl].contains(declaration.kind) else {
            throw MacroDiagnostics.errorMacroUsage(message: "Can only be applied to a class or actor")
        }
        // TODO: inheritance check for classes
        return [("Equatable", nil) ]
    }

    public static func expansion<Declaration: DeclGroupSyntax,
                                 Context: MacroExpansionContext>(of node: AttributeSyntax,
                                                                 providingMembersOf declaration: Declaration,
                                                                 in context: Context) throws -> [DeclSyntax] {
        guard declaration.as(ClassDeclSyntax.self)?.inheritanceClause == nil else {
            throw MacroDiagnostics.errorMacroUsage(message: "Can only be applied to a root class")
        }
        guard let identifier = declaration.as(ClassDeclSyntax.self)?.identifier.text ?? declaration.as(ActorDeclSyntax.self)?.identifier.text else {
            return []
        }
        let variables = declaration.memberBlock.members.compactMap({ $0.decl.as(VariableDeclSyntax.self)?.bindings.first?.pattern.as(IdentifierPatternSyntax.self)?.identifier.text }).map {
            "lhs.\($0) == rhs.\($0)"
        }.joined(separator: "\n&& ")

        return [
            DeclSyntax(
          """
          static func == (lhs: \(raw: identifier), rhs: \(raw: identifier)) -> Bool {
          \(raw: variables)
          }
          """
            )
        ]
    }
}

I think the compiler didn't take the macro generated code into consideration when it comes to check if the Equatable protocol conformance. Is it a compiler bug?

Great, this will be addressed by extension macro. Thanks.