Skip to content

New warning when public protocol requirement is satisfied via another, non-public protocol #86279

@grynspan

Description

@grynspan

Apple Swift version 6.3-dev (LLVM 9aac83f07b93962, Swift e364237)
Target: arm64-apple-macosx26.0
Build config: +assertions

The following library code compiles without warnings in Swift 6.2:

public protocol A {
    func f()
}

internal protocol B: A {}

extension B {
    public func f() {}
}

public struct S: A, B {}

Using the latest Swift 6.3 toolchain, it produces a new warning:

[1/1] Planning build
Building for debugging...
/Users/jon/Desktop/tmp/Sources/tmp/tmp.swift:14:15: warning: method 'f()' must be as accessible as its enclosing type because it matches a requirement in protocol 'A'
 9 | 
10 | extension B {
11 |     public func f() {}
   |                 `- note: mark the instance method as 'public' to satisfy the requirement
12 | }
13 | 
14 | public struct S: A, B {}
   |               `- warning: method 'f()' must be as accessible as its enclosing type because it matches a requirement in protocol 'A'
15 | 
/Users/jon/Desktop/tmp/Sources/tmp/tmp.swift:14:15: warning: method 'f()' must be as accessible as its enclosing type because it matches a requirement in protocol 'A'
 9 | 
10 | extension B {
11 |     public func f() {}
   |                 `- note: mark the instance method as 'public' to satisfy the requirement
12 | }
13 | 
14 | public struct S: A, B {}
   |               `- warning: method 'f()' must be as accessible as its enclosing type because it matches a requirement in protocol 'A'
15 | 

This particular pattern is useful for sharing common internal-only protocol requirements among public-facing types. For example:

public protocol A {
    func f()
}

internal protocol B: A {
    func g()
}

extension B {
    public func f() {
        g()
    }
}

public struct S: A, B {
    // implementation of f() calls g() automatically, but g() doesn't need to be a requirement of A, just B
    func g() {}
}

If it is intentional that a warning be emitted here, the specific message should be clarified because right now it just tells you to make an already-public member public.

Metadata

Metadata

Assignees

No one assigned

    Labels

    access controlFeature → modifiers: Access control and access levelsbugA deviation from expected or documented behavior. Also: expected but undesirable behavior.compilerThe Swift compiler itselfprotocolFeature → type declarations: Protocol declarationsprotocol compositionsFeature → types: protocol composition types

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions