swiftlang / swiftlang/swift-syntax
MacroSystem expansion detached nodes lose diagnostic context
- Dominant language
- Swift
- Stars
- 3.7k
- Forks
- 553
- Avg merge
- 5d 13h
- Merged PRs (30d)
- 16
Description
### Description
Macro expansions create diagnostics that are not relative to the given context (because they're `detached`), which means that there's no way to collocate diagnostics with the original source.
### Steps to Reproduce
You can take the `AddBlocker` macro demo from [swift-macro-examples](/DougGregor/swift-macro-examples) and expand the given macro:
```swift
let x = 1
let y = 2
let z = 3
#addBlocker(x * y + z)
```
If you expand as is, the context's diagnostic for the "+" will be relative to the `#addBlocker` expression macro node, not the entire source (starting at `let x = 1`), so formatting the diagnostics against the original source will render the diagnostic in the wrong place:
```swift
let x = 1
let y = 2
// ╰─ warning: blocked an add; did you mean to subtract?
let z = 3
#addBlocker(x * y + z)
```
It can be rendered correctly by _not_ detaching the context during expansion [here](https://github.com/apple/swift-syntax/blob/f6953015ba2d8c97df61760b614c59c084b72c7d/Sources/SwiftSyntaxMacroExpansion/MacroSystem.swift#L83):
```diff
-node: node.detach(in: context),
+node: node, //.detach(in: context),
```
```swift
let x = 1
let y = 2
let z = 3
#addBlocker(x * y + z)
// ╰─ warning: blocked an add; did you mean to subtract?
```
Diagnostics added during expansion should ideally be adjusted from where they were detached.
Contributor guide
Assessment
This issue has not been assessed yet.