Skip to content

Swift 6.1 compiler allows errors referencing invalid declarations to suppress macro expansion #80132

@seanwoodward

Description

@seanwoodward

Description

The Swift 6.1 compiler allows a reference to an invalid declaration error to suppress macro expansion without emitting an error. The issue is of particular concern when the macro suppressed is Swift Testing's #expect. In these circumstances tests pass when they should fail.

Reproduction

Using Swift Development Snapshot and the code in InvalidDeclarationErrorSuppressed, run the following command:

swift test --filter hideNonZeroCompilerError

Expected behavior

The macro should expand as expected or the compiler should emit an error.

Environment

Apple Swift version 6.1-dev (LLVM 08670c03fe16573, Swift 493744d)
Target: arm64-apple-macosx15.0

Additional information

In a test similar to those in the swift-syntax macro tests, the macro expands when parsed with Parser.parse and expanded using BasicMacroExpansionContext and does not reproduce the error.

import SwiftDiagnostics
import SwiftOperators
import SwiftParser
import SwiftParserDiagnostics
import SwiftSyntax
import SwiftSyntaxMacroExpansion
import SwiftSyntaxMacros
import Testing


struct SwiftSyntaxParserExpansionTests {
  struct HideNonZeroErrorMacro: ExpressionMacro {
    static func expansion(of macro: some SwiftSyntax.FreestandingMacroExpansionSyntax, in context: some SwiftSyntaxMacros.MacroExpansionContext) throws -> SwiftSyntax.ExprSyntax {
      return ExprSyntax("print(\"*** Expanded! ***\")")
    }
  }
  
  @Test func expandMacroWithParserParse() throws {
    let originalSource = """
    protocol Foo<Bar> {
    associatedtype Bar
    var bar: Bar { get }
    }
    struct Conforms: Foo {
    let bar: Int = 0
    }
    
    let explicit: Conforms = Conforms()
    
    #hideNonZeroError((explicit as Foo<Int>).bar == explicit.bar)
    """
    let parsedSource = Parser.parse(source: originalSource)
    
    let macros: [String: MacroSpec] = ["hideNonZeroError": .init(type: HideNonZeroErrorMacro.self)]
    
    let context = BasicMacroExpansionContext.init(
      sourceFiles: [parsedSource: .init(moduleName: "TestModule", fullFilePath: "test.swift")]
    )
    
    let expandedSourceFile = parsedSource.expand(
      macroSpecs: macros,
      contextGenerator: { BasicMacroExpansionContext(sharingWith: context, lexicalContext: $0.allMacroLexicalContexts()) }
    )

    print(parsedSource.debugDescription)

    print(expandedSourceFile.debugDescription)
  }
  
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugA deviation from expected or documented behavior. Also: expected but undesirable behavior.triage neededThis issue needs more specific labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions