I have tweaked the type checker to allow that. I have also tweaked getContextSubstitutions() to substitute the types, although I am not sure if I have done that correctly.
I have also put emitNestedTypeDecls(protocol->getMembers()) inside emitProtocolDecl, however it has trouble emitting the metadata for the struct (crashes in type converter). If you change the struct to a class, then the crash is in useConformance (because the protocol conformance ref is invalid).
Seems like I am missing something or the type substitution isn't working correctly.
The type of 'self' inside a method of A.B must not be A.B, but Self.B where Self is the outer type parameter from the protocol A. However NominalType cannot model that right now.
I think a first step would be the planned changes to unify BoundGenericNominalType and NominalType, and change BoundGenericNominalType to store a substitution map instead of an array of generic arguments together with a parent type. Then the requisite changes to handle substitutions would be trivial.
I don't think there are any concrete plans yet, but if you're interested, merging NominalType into BoundGenericNominalType would be a good first step.
And yeah, I think nesting protocols inside non-generic concrete types is much easier than the other direction and should not require any major representational changes.
Unfortunately it hasn't moved since Swift 3, even though everyone seems to agree about it there. I don't know why it was closed either for no good reason. Can we re-open it and push it along further?
Hi @Karl, your PR hasn‘t moved forward for several month. I wonder if you still intend to push it forward or would you like someone else to take over it (maybe @suyashsrijan)?!
I have something working, just need to write some tests. I’ll try to do that in the next few days.
It’s pretty basic - just putting protocols inside other types, but that’s a good start and would be nice to get it merged first before we think about putting other types inside protocols (esp. since its related to generic protocols).
They actually provide a fairly terrible solution. The only time they perform adequately is when using someone else's module. When writing your own (your app is a single module, by default), you might find that namespacing is useful for organization purposes, but that the overhead of a module is not worth the cost. This usually leads to language hacks such as uninhabited enums.
Personally, I have come across many instances where I had a collection of related static functions with which I did not want to pollute the global namespace. Also, I wanted it clear that the functions are indeed related. So I use uninhabited enums. I'm not going to create a module for half-a-dozen or fewer functions.
Currently the best hack to allow nesting protocols inside of other types is to use a typealias. So given the common MyView.Delegate use-case, you could write something like: