swiftlang / swiftlang/swift-syntax

Equality check fails for AttributeSyntax and SyntaxIdentifier when expanding attached macro

Open
#1,800 2 comments 0 reactions 0 assignees View on GitHub
Macros
Dominant language
Swift
Stars
3.7k
Forks
554
Avg merge
6d 8h
Merged PRs (30d)
22

Description

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

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

public struct MyMacro: PeerMacro {
public static func expansion(
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.
```swift
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.
```swift
class Example {
@myMacro // 2 errors: "RetrievedAttribute != node" and "RetrievedAttribute!.id != node.id"
func foo() {}
}
```

**Steps to reproduce**

Project archive: [MyMacro.zip](https://github.com/apple/swift/files/11759715/MyMacro.zip)
Or [Github repo](https://github.com/alimyuz/MacroEquatableIssue)

**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

Contributor guide

Open the contributing guide

Research direction

Start with the linked reproduction project, comparing the assertMacroExpansion() test with the attached macro invocation in main.swift. Trace AttributeSyntax and SyntaxIdentifier equality during real macro expansion; done means both comparisons succeed without diagnostics in the reproduced source case.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.