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

Visibility Issue with ExtensionMacro in Different Files When Attached to Protocol #74644

Open
hainayanda opened this issue Jun 22, 2024 · 0 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. swift macro Feature → declarations: Swift `macro` declarations

Comments

@hainayanda
Copy link

Description

It appears that extension methods generated by ExtensionMacro attached to protocols are not visible across different files. This issue persists even though it was previously reported and marked as closed.

Reproduction

// Inside my MacroCompilerPlugin Module

public struct FooExtensionMacro: ExtensionMacro {
    public static func expansion(of node: AttributeSyntax, attachedTo declaration: some DeclGroupSyntax, providingExtensionsOf type: some TypeSyntaxProtocol, conformingTo protocols: [TypeSyntax], in context: some MacroExpansionContext) throws -> [ExtensionDeclSyntax] {
        let decl: DeclSyntax =
        """
        extension Foo {
          var foo: String { "foo" }
          func printFoo() {
            print(foo)
          }
        }
        """
        guard let extensionDecl = decl.as(ExtensionDeclSyntax.self) else {
            return []
        }
        
        return [extensionDecl]
    }
}

// Inside my MacroLibrary module

@attached(extension, names: named(foo), named(printFoo))
public macro FooExtension() = #externalMacro(module: "MacroCompilerPlugin", type: "FooExtensionMacro")

// Inside the client project / final target

import MacroLibrary

@FooExtension    // <--- apply the macro to generate default property and method
protocol Foo {
    var foo: String { get }
}

/// The above correctly expands to:
///
/// protocol Foo {
///   var foo: String { get }
/// }
///
/// extension Foo {
///   var foo: String { "foo" }
///   func printFoo() {
///     print(foo)
///   }
/// }

extension String: Foo { }   // <--- This compiles! Hooray, that means the default implementation of the property foo from the extension macro worked!

"Test".printFoo()   // <--- This doesn't compile ("Value of type ''String" has no member 'printFoo'"). This seems to indicate that the compiler can't "see" the printFoo() extension method from the ExtensionMacro, even though it can see the default implementation of the protocol's foo property from the same macro.

Expected behavior

"Test".printFoo() // <-- Should compile and print "foo" based on the extension method synthesized by the ExtensionMacro

Environment

swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)
Xcode: Version 15.4 (15F31d)
Target: arm64-apple-macosx14.0

Additional information

It was noted in the previous issue (reference: #69073) that the visibility problem occurs only in different files. When all the related code is in the same file, the generated extension methods are visible and work as expected.

// Same file
import MacroLibrary

@FooExtension
protocol Foo {
    var foo: String { get }
}

extension String: Foo { }

"Test".printFoo()   // prints "foo"

However, the method is not visible if the call to printFoo() is made in a different file.

// Different file
"Test".printFoo()  // <---- Error: "Value of type ''String" has no member 'printFoo'"

This behavior suggests that the ExtensionMacro added members might be scoped as fileprivate even when generated with an internal or even public modifier.

@hainayanda hainayanda added bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. triage needed This issue needs more specific labels labels Jun 22, 2024
@hborla hborla added swift macro Feature → declarations: Swift `macro` declarations and removed triage needed This issue needs more specific labels labels Jul 14, 2024
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. swift macro Feature → declarations: Swift `macro` declarations
Projects
None yet
Development

No branches or pull requests

2 participants