swiftlang / swiftlang/swift-syntax
Equality check fails for AttributeSyntax and SyntaxIdentifier when expanding attached macro
- 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
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