I have an extension macro that is intended to be applied to protocol declarations. The macro provides default implementations of all of its members via an extension. If I declare a struct or class Foo which implements the protocol via those default implementations, I am only able to access the protocol members on an instance of Foo from the same file in which Foo was declared. Anywhere else in the same module, I get a "Value of type 'Foo' has no member 'member'" error. (fooInstance as Proto).member does work in either file, however.
4. Replace source of `ProtocolMembersClient/main.swift` with the following. Note that `NonWorking{Protocol, Struct}` only differ from their `Working*` counterparts in that `property` is provided by a macro instead of having been added manually:
```swift
import ProtocolMembers
// =============== Working stuff ===============
protocol WorkingProtocol {
var property: Int { get }
}
extension WorkingProtocol {
var property: Int { 42 }
}
struct WorkingStruct: WorkingProtocol {
}
// ============= Non-working stuff =============
@ImplementProtocolMembers
protocol NonWorkingProtocol {
var property: Int { get }
}
struct NonWorkingStruct: NonWorkingProtocol {
}
// ================== Testing ==================
func takeValuesInSameFile(working: WorkingStruct, nonWorking: NonWorkingStruct) {
// In this file, all three of these lines compile (as expected):
_ = working.property
_ = (nonWorking as any NonWorkingProtocol).property
_ = nonWorking.property
}
Finally, add another Swift file in ProtocolMembersClient with the following source:
// ================== Testing ==================
func takeValuesInSecondaryFile(working: WorkingStruct, nonWorking: NonWorkingStruct) {
// In this file, these two lines compile:
= working.property
= (nonWorking as any NonWorkingProtocol).property
// But this one does not (unexpected):
// _ = nonWorking.property
}
### Expected behavior
I expected that `property` would be accessible on instances of `NonWorkingStruct` regardless of which file in the module the access occurs in.
### Environment
Tested on Swift 5.9 included with Xcode, as well as the current development snapshot as of writing:
% swift -version
swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)
Description
I have an extension macro that is intended to be applied to protocol declarations. The macro provides default implementations of all of its members via an extension. If I declare a struct or class
Foo
which implements the protocol via those default implementations, I am only able to access the protocol members on an instance ofFoo
from the same file in whichFoo
was declared. Anywhere else in the same module, I get a "Value of type 'Foo' has no member 'member'" error.(fooInstance as Proto).member
does work in either file, however.Reproduction
Full code also available here.
Steps to reproduce:
ProtocolMembers
ProtocolMembers/ProtocolMembers.swift
with the following:ProtocolMembersMacros/ProtocolMembersMacro.swift
with the following:public struct ImplementProtocolMembersMacro: ExtensionMacro { public static func expansion(of node: SwiftSyntax.AttributeSyntax, attachedTo declaration: some SwiftSyntax.DeclGroupSyntax, providingExtensionsOf type: some SwiftSyntax.TypeSyntaxProtocol, conformingTo protocols: [SwiftSyntax.TypeSyntax], in context: some SwiftSyntaxMacros.MacroExpansionContext) throws -> [SwiftSyntax.ExtensionDeclSyntax] { [ try ExtensionDeclSyntax("extension NonWorkingProtocol") { "var property: Int { 42 }" } ] } }
@main struct ProtocolMembersPlugin: CompilerPlugin { let providingMacros: [Macro.Type] = [ ImplementProtocolMembersMacro.self ] }
ProtocolMembersClient
with the following source:func takeValuesInSecondaryFile(working: WorkingStruct, nonWorking: NonWorkingStruct) { // In this file, these two lines compile: = working.property = (nonWorking as any NonWorkingProtocol).property
}
% swift -version swift-driver version: 1.87.1 Apple Swift version 5.9 (swiftlang-5.9.0.128.108 clang-1500.0.40.1)