Understanding Protocol Generic Self

Recently while giving an internal talk at The App Business on Type Erasure I noticed myself not really understanding the true nature of Self (so deep) in a Generic Protocol. Through some hugely productive discussion with my co workers I arrived at a greater understanding of how the compiler interprets Self but I still have a long way to go. It all started with this,

protocol SelfExaminer {
    func examineInstanceOfSelf(selfInstance: Self) -> Self
}

A rather silly protocol that I was using so I could demonstrate Type Erasure. If you are unfamiliar with Typer erasure check out these awesome blog posts which brilliantly explain the process.

As we know a generic protocol like this will cause me issues if I try to use this protocol as a Type. What I found interesting is the following protocol does not cause me any problems when I try to use it as a Type.

func examineInstanceOfSelf(selfInstance: Int) -> Self

We still have a generic Self requirement but suddenly swift no longer complains. If we take our original protocol and try to use a function we can see why this causes problems very clearly

protocol SelfExaminer {
    func examineInstanceOfSelf(selfInstance: Self) -> Self
}

func someFunction(examiner: SelfExaminer) {
    examiner.examineInstanceOfSelf(????)
}

What I struggle to understand is why Swift is totally ok with the following

protocol SelfExaminer {
    func examineInstanceOfSelf(selfInstance: Int) -> Self
}

func someFunction(examiner: SelfExaminer) {
    let someSelfExaminer = examiner.examineInstanceOfSelf(4)
}

Surely now we don't know the type of someSelfExaminer, if we look at it in the editor we can see that it has a Self Examiner type.

This took me a little time to wrap my head around but it makes sense as in this context you will only ever be able to treat it as a SelfExaminer. With input parameters this is obviously far less acceptable as the function would expect a full implementation of Self.