I think the correct answer is the first option, but I'm not entirely clear we're using the same terminology. I'll try to explain the precise behavior.
First, this is all about "Self" inside protocols (and protocol extensions). "Self" behaves like a generic parameter type here. What does this mean? Well, first, let's look at an example involving a concrete generic type:
struct Generic<T> {
typealias A = (T, T)
}
What does it mean when I write something like Generic<Int>.A
? The compiler takes the underlying type for A
, which is (T, T)
, and replaces each occurrence of T
with its substitution from the base type Generic<Int>
, which is Int
. So Generic<Int>.A
is (Int, Int)
.
Now let's suppose we have a protocol typealias, for example something like:
protocol P {
typealias A = Array<Self>
}
struct S : P {}
When I write S.A
, we again take the underlying type of A
, which is Array<Self>
, and substitute in a replacement type for Self
. In this case though, instead of looking at the generic parameters of the base type S
, the replacement type for a protocol's Self
is S
itself. So S.A
is Array<S>
.
In your first example,
extension UIView {
var _view: StaticSelf {
return self
}
}
It helps to think of an unqualified reference like StaticSelf
as having a base type of its context, which is UIView
. So it's equivalent to declaring var _view: UIVIew.StaticSelf
. Following the above rules, the result is UIView
.
Similarly, if you have:
extension UIButton {
var _button: StaticSelf {
return self
}
}
The reference to StaticSelf
inside an extension of UIButton
is equivalent to having written UIButton.StaticSelf
, which is equivalent to UIButton
.
Inside a struct or enum, Self
is equivalent to writing out the name of the type. So yes, you can use Self
in a concrete type context to implement a witness for a protocol requirement that has the protocol Self
in its type.
Inside a class, Self
is something different. It means the dynamic type of the self
parameter; and in declaration signatures, it is only valid as the return type of a method, with at most one level of optionality. This has not changed between 5 and the swift-5.1-branch (which has the SE-0068 implementation).
What SE-0068 does allow you to do is to refer to Self
inside the body of a method. Previously, you could manipulate values of type Self
, define new variables who type contains Self
via inference, and even call generic functions with a substitution involving Self
, but you had no way to spell a type containing Self
which sometimes required awkward workarounds. Now you can.
In your example, you define a typealias with an underlying type of Self
inside a class:
This should be an error. Please file a bug. Eventually we can allow it, but it would require additional checks that were not added as part of SE-0068.