Is it just me or did we end up having partly `StaticSelf` in Swift?

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.

13 Likes