Skip to content
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

Freestanding macros cannot unbox an existential argument #73593

Open
eliyap opened this issue May 13, 2024 · 0 comments
Open

Freestanding macros cannot unbox an existential argument #73593

eliyap opened this issue May 13, 2024 · 0 comments
Labels
feature A feature request or implementation triage needed This issue needs more specific labels

Comments

@eliyap
Copy link

eliyap commented May 13, 2024

Motivation

SE-0382 states

Macros ... can be overloaded in the same way as functions, so long as the argument labels, parameter types, or result type differ.

I am overloading a macro to swap macro implementations based on a protocol conformance.
i.e. if MyType conforms to MyProtocol, expand to this, otherwise expand to that.

For example, we can modify #stringify to require a CustomStringConvertible argument

@freestanding(expression)
public macro stringify<SomeStringConvertible: CustomStringConvertible>(_ value: SomeStringConvertible) -> String
    = #externalMacro(module: "ExistentialOverloadMacros", type: "StringifyMacro")

public struct StringifyMacro: ExpressionMacro {
    public static func expansion(of node: some FreestandingMacroExpansionSyntax, in context: some MacroExpansionContext) -> ExprSyntax {
        guard let argument = node.argumentList.first?.expression else {
            fatalError("compiler bug: the macro does not have any arguments")
        }

        return #""\(\#(argument))""#
    }
}

Description

With a normal Swift function, a function accepting some CustomStringConvertible can implicitly unbox an argument of type any CustomStringConvertible.
This ability is described in SE-0352, Implicit Open Existentials
However, our modified #stringify cannot.

let a = 17
let b = 25

func printOut(_ value: some CustomStringConvertible) {
    print("The value was '\(value)'")
}

let convertible: any CustomStringConvertible = a + b

printOut(convertible) // ok
print("The value was \"\(#stringify(a + b))\"") // ok
print("The value was \"\(#stringify(convertible))\"")
// Error: Type 'any CustomStringConvertible' cannot conform to 'CustomStringConvertible'

Proposed solution

Similar to Swift functions, I would like macros with an argument of type some Protocol to accept a value of type any Protocol.

Alternatives considered

No response

Additional information

No response

@eliyap eliyap added feature A feature request or implementation triage needed This issue needs more specific labels labels May 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature A feature request or implementation triage needed This issue needs more specific labels
Projects
None yet
Development

No branches or pull requests

1 participant