Skip to content

Expression macros should support opaque return types #85216

@benpious

Description

@benpious

Description

If I want to return some conforming type from an expression macro, I can't. The compiler specifically says that this is not supported, and I can only return an existential or a concrete type.

Reproduction

@freestanding(expression)
public macro MyMacro(
    _ id: StaticString
) -> some Thing = #externalMacro(
    module: "MyMacros",
    type: "MyMacro"
)

protocol Thing {
     static var name: String { get }
}

where the macro might be invoked like

Text(...).someSwiftUIModifier(MyMacro("something")) // where someSwiftUIModifier is generic, so if `MyMacro` returns an existential compilation will fail

and where the macro would generate something like

{
     struct __something {
            static var name = "something"
     }
     return __something()
}()

Expected behavior

This would be allowed; without it macros are less expressive than writing the code manually.

Environment

swift-driver version: 1.120.5 Apple Swift version 6.1.2 (swiftlang-6.1.2.1.2 clang-1700.0.13.5)

Additional information

The use case for this would be creating a new type inside of the expression and then returning it. Today I can only return an existential, so the type is lost. I can probably work around this by switching from an expression macro to a freestanding macro, but it won't be nearly as nice for the caller.

I could see an argument that this is changing the meaning of some a little, since it normally means "this function returns one type, but the author doesn't want you to know what it is" and now it means "this function returns a different type every time, and you can't know what it is because it's only in scope here." Idk if supporting some here is the right behavior, but I do think that the code I posted should be allowed to work.

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