-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Description
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)
}
}