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

Adrian Zubarev adrian.zubarev at devandartist.com
Sat Jun 25 03:44:58 CDT 2016


Originally I started this topic in a discussion thread but moved it now into its own proposal thread due the lack of feedback.

This proposal contains a breaking change!

You can read a formatted version here: https://gist.github.com/DevAndArtist/8f1113b6d5d0379ebf82bd227cf4a88d

Feel free to also provide feedback if you spot any typos or language mistakes I might have made.

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 extension 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.

Public Api:

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 { … }

public 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.



-- 
Adrian Zubarev
Sent with Airmail
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160625/e80e355c/attachment.html>


More information about the swift-evolution mailing list