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

[SR-5880] Allow internal declarations in public protocol #48450

Open
swift-ci opened this issue Sep 13, 2017 · 2 comments
Open

[SR-5880] Allow internal declarations in public protocol #48450

swift-ci opened this issue Sep 13, 2017 · 2 comments
Labels
compiler The Swift compiler in itself conformances Feature → protocol: protocol conformances feature A feature request or implementation swift evolution proposal needed Flag → feature: A feature that warrants a Swift evolution proposal

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-5880
Radar None
Original Reporter Reitzig (JIRA User)
Type New Feature
Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels New Feature, LanguageFeatureRequest
Assignee None
Priority Medium

md5: 8c72427c6c260c57232fcd4732a6fb7a

Issue Description:

In writing a library that wraps a REST API, I find myself writing protocols for shared functionality. For instance, every Resource should have an ID and be serializable to the JSON format the REST API uses; but I only want some of those functions to be public! Since public protocols can not have internal declarations, I have to construct something like this:

public protocol Foo {
    func foo()
}

internal protocol InternalFoo: Foo {
    func bar()
}

public struct MyFoo: InternalFoo {
    public func foo() {}

    internal func bar() {}
}

public func doStuff(f: Foo) throws {
    guard let internalF = f as? InternalFoo else {
        throw "you can't use Foo except my Foo!"
    }

    internalF.foo()
    internalF.bar()
}

As we can see, I enforce that doStuff only ever receives values whose implementation I have created. Other modules can implement types conforming to Foo but not InternalFoo. However, the check is dynamic – meh.

Compare with this (currently illegal) code:

public protocol Foo {
    func foo()
    internal func bar()
}

public struct MyFoo: InternalFoo {
    public func foo() {}
    internal func bar() {}
}

public func doStuff(f: Foo) throws {
    f.foo()
    f.bar()
}

Here, the intent is much clearer!

Of course, other modules can not implement types conforming to Foo now. I'd argue that this is what we want here; a compiler message along the lines of "Conformance to Foo is not possible because not all declarations are accessible" should be clear enough.

We can also make this explicit by lifting the difference between public and open from classes: only protocols declared open can be conformed to outside of their own module, but those can not have internal declarations. This would be a source-breaking change, even though migration would be trivial: all protocols written with the current semantics would have to get open instead of public.

@belkadan
Copy link
Contributor

Obligatory "this needs to go through the Swift Evolution Process". :-)

@swift-ci
Copy link
Collaborator Author

Comment by Raphael (JIRA)

I was afraid you'd say that! 😛 No, of course it has to. I keep hoping that if one of my ideas has merit, a more involved (and more qualified) community member might pick it up and move it through SEP. And that in case they are absolutely idiotic, a quick "no way" comment would appear here. 😉

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
@AnthonyLatsis AnthonyLatsis added swift evolution proposal needed Flag → feature: A feature that warrants a Swift evolution proposal conformances Feature → protocol: protocol conformances and removed new feature labels Nov 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler The Swift compiler in itself conformances Feature → protocol: protocol conformances feature A feature request or implementation swift evolution proposal needed Flag → feature: A feature that warrants a Swift evolution proposal
Projects
None yet
Development

No branches or pull requests

3 participants