Skip to content

Fix-it Application Failure in assertMacroExpansion Function #2332

Closed
@Matejkob

Description

@Matejkob

Description

The fix-it provided by a peer macro is correctly applied by the compiler, yet the assertMacroExpansion function fails to apply it appropriately.

Steps to Reproduce

  1. Reference the example Macro from SwiftSyntax repository: https://github.com/apple/swift-syntax/blob/098b177830c0d2e614b3757241b2572d758f9143/Examples/Sources/MacroExamples/Implementation/Peer/AddCompletionHandlerMacro.swift#L18-L164
  2. Utilize the macro in the code as shown:
    struct Test {
      @AddCompletionHandler
      func fetchData() -> String {
        return "Hello, World!"
      }
    }
    The macro generates a diagnostic with a fix-it add 'async'.
  3. When the fix-it is applied using the compiler, the async keyword is correctly inserted before -> String.
  4. Construct a unit test to validate this scenario:
    func testExpansionOnNonAsyncFunctionAppliesFixIt() {
      assertMacroExpansion(
        """
        struct Test {
          @AddCompletionHandler
          func fetchData() -> String {
            return "Hello, World!"
          }
        }
        """,
        expandedSource: """
          struct Test {
            func fetchData() -> String {
              return "Hello, World!"
            }
          }
          """,
        diagnostics: [
          DiagnosticSpec(
            message: "can only add a completion-handler variant to an 'async' function",
            line: 3,
            column: 3,
            severity: .error,
            fixIts: [FixItSpec(message: "add 'async'")]
          )
        ],
        macros: macros,
        applyFixIts: ["add 'async'"],
        fixedSource: """
        struct Test {
          @AddCompletionHandler
          func fetchData() async -> String {
            return "Hello, World!"
          }
        }
        """,
        indentationWidth: .spaces(2)
      )
    }
    The expectation is for the test to pass, but it fails. The fixedSource string produced by the assertMacroExpansion function erroneously manifests as:
    struct Test {
      @AddCompletionHandler
      f() async -> String () -> String {
        return "Hello, World!"
      }
    }
    Notice the incorrect placement and duplication of the function signature, suggesting that the fix-it application is not handling the source code transformation as intended.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions