Skip to content

Empty Lexical Context When Expanding Expression Macro as Argument's Default Value #81749

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
filip-sakel opened this issue May 23, 2025 · 1 comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels

Comments

@filip-sakel
Copy link
Contributor

Description

I'm trying to use a freestanding expression macro as the default value of a function argument, as outlined in SE-0422. This macro accesses the lexical context, which is unfortunately empty when the macro is expanded as the default value to an argument. I can only get the lexical context when explicitly passing in the macro to the argument.

Reproduction

Client.swift

@freestanding(expression)
public macro _environmentValuesContext() = 
    #externalMacro(module: "Macro", type: "EnvironmentValuesMacro")

struct MyStruct {
    func useContext(_ context: Void = #_environmentValuesContext) {}

    func run() {
        // Nothing when expanded as the default value for the argument
        useContext() // Lexical context: [] (from macro '_environmentValuesContext')

        // Correct context when passing macro explicitly
        useContext(#_environmentValuesContext) // Lexical context: [FunctionDeclSyntax ...
    }
}

Macro.swift

import SwiftSyntax
import SwiftSyntaxMacros
import SwiftCompilerPlugin
import SwiftDiagnostics

@main
struct Macro: CompilerPlugin {
    let providingMacros: [Macro.Type] = [
        EnvironmentValuesMacro.self,
    ]
}

public struct EnvironmentValuesMacro: ExpressionMacro {
    public static func expansion(
        of node: some FreestandingMacroExpansionSyntax, 
        in context: some MacroExpansionContext
    ) throws -> ExprSyntax {
        context.diagnose(Diagnostic(
            node: node, 
            message: SimpleDiagnosticMessage(
                message: "Lexical context: \(context.lexicalContext)", 
                severity: .error
            )
        ))
        return "()"
    }
}

Expected behavior

I would expect that the lexical context is passed to the macro even when the macro is expanded as the argument's default value, i.e. useContext() and useContext(#_environmentValuesContext) should yield the same result.

Environment

Swift version 6.2-dev (LLVM f3274059e0a182e, Swift 442f25d)
Target: aarch64-unknown-linux-gnu
Build config: +assertions

Additional information

No response

@filip-sakel filip-sakel added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels May 23, 2025
@ValentinWalter
Copy link

I recently ran into this too. Hoping it's indeed a bug and not intentional. My use case is a #sourceLocation macro that reads the lexical context to provide a rich description of the source location to a logger.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels
Projects
None yet
Development

No branches or pull requests

2 participants