[swift-evolution] [Proposal] Revising access modifiers on extensions

Adrian Zubarev adrian.zubarev at devandartist.com
Sun Jun 26 13:59:24 CDT 2016


Proposal is moved to a git repo: https://github.com/DevAndArtist/swift-evolution/blob/extensions_access_modifiers/proposals/nnnn-extensions-access-modifiers.md

I also updated a few things for readability.
Revising access modifiers on extensions

Proposal: SE-NNNN
Author: Adrian Zubarev
Status: Awaiting review
Review manager: TBD
Introduction

One great goal for Swift 3 is to sort out any source breaking language changes. This proposal aims to fix access modifier inconsistency on extensions compared to other scope declarations types.

Swift-evolution thread: [Proposal] Revising access modifiers on extensions

Motivation

When declaring members on extensions which don’t have an explicit access modifier in Swift 2.2, it is possible to create an implicitly public extension by applying a public modifier to at least one extension member.

public struct A { … }

// Implicitly public  
extension A {
    public var member1: SomeType { … }
     
    // Implicitly internal  
    func member2() { … }
}

// Implicitly internal
extension A {

    // Implicitly internal
    var member3: SomeType { … }
}
Furthermore in Swift 2.2 it is not allowed to apply an access modifier on extensions when a type inheritance clause is present:

public protocol B { … }

// 'public' modifier cannot be used with
// extensions that declare protocol conformances
public extension A : B { … }
Proposed solution

Allow access modifier on extensions when a type inheritance clause is present.

Remove the behavior of an implicit public extension.

This changes should make access modifier on extensions consistent to classes, structs and enums (and SE–0025).

The current grammar will not change:

extension-declaration → access-level-modifieropt extension type-identifier type-inheritance-clauseopt extension-body

extension-declaration → access-level-modifieropt extension type-identifier requirement-clause extension-body

extension-body → { declarationsopt }

Iff the access-level-modifier is not present, the access modifier on extensions should always be implicitly internal.

Impact on APIs:

Current version:

/// Implementation version
///========================

public protocol Y {
    func member()
}

public struct X { … }

// Implicitly public
extension X : Y {
    public func member() { ... }
     
    // Implicitly internal
    func anotherMember() { ... }
}

/// Imported modele version
///========================

public protocol Y {
    func member()
}

public struct X { ... }

// Missing `public` modifier
extension X : Y {
    public func member() { ... }
}
New Version:

/// Implementation version
///========================

public extension X : Y {
    public func member() { ... }
     
    // Implicitly internal  
    func anotherMember() { ... }
}

/// Imported modele version
///========================

public extension X : Y {
    public func member() { ... }
}
Impact on existing code

This is a source-breaking change that can be automated by a migrator, by simply scanning the extension-body for at least one public modifier on its members. Iff a public modifier was found on any member, the migrator can add an explicit public modifier to the extension itself.

Alternatives considered

No other alternative were considered for this proposal.
Rationale

On [Date], the core team decided to (TBD) this proposal. When the core team makes a decision regarding this proposal, their rationale for the decision will be written here.



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160626/6c18681d/attachment.html>


More information about the swift-evolution mailing list