[apple/swift-evolution] Ease restrictions on protocol nesting (#552)


(Slava Pestov) #1

@slavapestov <https://github.com/slavapestov> I can't reply to your comments directly so will have do batch them here:

With the current implementation of name lookup, qualified and unqualified lookup will find the nominal type as a member of the conforming type. In Swift 3 there was a bug where unqualified name lookup didn't find a typealias, but this is fixed now.

I think the nicest rule would be that, if the nested type is used by a protocol requirement, it does actually get imported in to the namespace of the conforming type (the compiler would generate a hidden typealias). That way, you would actually get something called Float.Sign and Double.Sign, could refer to them as just Sign from extensions, etc.

For everything else (i.e. nested types which are not used by requirements and do not capture associated types), they likely have nothing to do with the conforming type. It makes sense then, that everybody should have to spell it as RandomAccessCollection.Concurrent<Array<Int>> and not just .Concurrent, regardless of whether or not the current context conforms to RandomAccessCollection.

This sounds too complex — the unqualified lookup implementation is tricky enough as-is, so let’s stick with the simplest rule that makes sense: unqualified lookup inside a concrete type will find all members (requirements, as well as nested types) of any protocol that the concrete type conforms to.

Slava

We leave the door open for capturing types (when they are possible) to be spelled differently, so you could maybe just write let myVar: Concurrent inside an extension of Array<Int> in order to get a RandomAccessCollection.Concurrent where Collection == Array<Int>.

At the very least, it is a separate proposal :slight_smile:

I'm worried that if we leave it, there may be ABI decisions we take now which make it unpalatable later. Even if this part of the proposal can't be implemented right away, it'd be nice to keep it; especially since you can have generic NSObject subclasses, and it's reasonable to want to have nested delegate protocols inside of them.

Once we figure out the right semantics for protocols inside generic types, we should be able to implement them without disturbing ABI. Again, speaking as someone who is likely to end up implementing this proposal were it to be accepted, it makes sense to tackle the non-generic protocol case first, even if the proposal has generic protocols.

Also, if we allow this:

struct G<T> {
  protocol P {
    func foo() -> T
  }
}

Why not go all the way and allow this?

protocol P<T> {
  func foo() -> T
}

They’re essentially equivalent.

But yeah, that’s definitely a separate proposal.

Slava

···

On Feb 5, 2017, at 10:06 AM, Karl <notifications@github.com> wrote:


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <https://github.com/apple/swift-evolution/pull/552#issuecomment-277536960>, or mute the thread <https://github.com/notifications/unsubscribe-auth/AAEDtgNnQ9dOU4Rtiw_4VwY996cICYqCks5rZg-egaJpZM4KqNwF>.