Skip to content

Equality check fails for AttributeSyntax and SyntaxIdentifier when expanding attached macro #1800

Open
@alimyuz

Description

@alimyuz

Description
The equality check for AttributeSyntax and its id property (SyntaxIdentifier) works in assertMacroExpansion() tests, but fails when expanding in "real" source code.

Macro:

@attached(peer, names: arbitrary)
public macro myMacro() = #externalMacro(module: "MyMacroMacros", type: "MyMacro")

public struct MyMacro: PeerMacro {
    public static func expansion<Context, Declaration>(
        of node: AttributeSyntax,
        providingPeersOf declaration: Declaration,
        in context: Context
    ) throws -> [DeclSyntax] where Context : MacroExpansionContext, Declaration : DeclSyntaxProtocol {
        guard let funcDecl = declaration.as(FunctionDeclSyntax.self) else { return [] }
        
        let retrievedAttribute = funcDecl.attributes?.compactMap { attributeSyntax in
            switch attributeSyntax {
            case .attribute(let attribute):
                return attribute
            default:
                return nil
            }
        }.first
        
        if retrievedAttribute != node {
            context.addDiagnostics(from: "retrievedAttribute != node", node: node)
        }
        if retrievedAttribute!.id != node.id {
            context.addDiagnostics(from: "retrievedAttribute!.id != node.id", node: node)
        }
        return []
    }
}

Test passes without any diagnostics. You can see that they are equal in the debugger too.

let testMacros: [String: Macro.Type] = [
    "myMacro": MyMacro.self,
]

final class MyMacroTests: XCTestCase {
    func testMacro() {
        assertMacroExpansion(
            """
            class Example {
                @myMacro
                func foo() {
                }
            }
            """,
            expandedSource:
            """
            class Example {
                func foo() {
                }
            }
            """,
            macros: testMacros
        )
    }
}

The same declaration but in main.swift. Compilation fails with 2 errors.

class Example {
    @myMacro  // 2 errors: "RetrievedAttribute != node" and "RetrievedAttribute!.id != node.id"
    func foo() {}
}

Steps to reproduce

Project archive: MyMacro.zip
Or Github repo

Environment

  • swift-driver version: 1.82.2 Apple Swift version 5.9 (swiftlang-5.9.0.114.6 clang-1500.0.27.1)
    Target: arm64-apple-macosx14.0
  • Xcode 15.0
    Build version 15A5160n
  • Deployment target: iOS 13

Metadata

Metadata

Assignees

No one assigned

    Labels

    MacrosIssues in the SwiftSyntaxMacro… modules

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions