It's because Type is a generic parameter, not a concrete type and you are trying to make it, a non-concrete type conforms to SubProtocol, which is also not a concrete type.
SubProtocol also doesn't "conform" to BaseProtocol, it inherits from or extends it.
This also smells of being a parallel class/protocol hierarchy. To be avoided.
Could the generics restriction here on using concrete types be lifted by using the new reverse generics? E.g. class SubClass: BaseClass<some SubProtocol>
Technically, you can, but it’s not a trivial addition (and likely need to go through SE), and very, very likely not what you want.
Should we really add it, at best
class SubClass: BaseClass<some SubProtocol>
would just be shortened version of
class SubClass: BaseClass<SomeConcreteTypeYouDontWantToTypeItOut>
Downstream users can only use SubClass, which is a subclass of BaseClass<SomeConcreteTypeYouDontWantToTypeItOut>, and nothing else. If this is what you want, just type the actual concrete type name out.
On the other hand,
class SubClass<T>: BaseClass<T> where T: SubProtocol
Leave T as a generic parameter. Downstream users can use SubClass<Int> and SubClass<String> which are subclasses of BaseClass<Int> and BaseClass<String> respectively, given that you conform Int and String properly.
It's not that I want to hide the concrete type because I don't want to type it out, it's because somewhere further in the chain of code making this use generic constraints runs into the issue “Protocol can only be used as a generic constraint because it has Self or associated type requirements.”, so starting here with a reverse generic would work. It seems technically possible to add and there might be some utility out of it.
Reverse Generic is not as powerful as you'd think.
The premise of Generic is that someone (implementor, user), doesn't need to know the concrete type.
If implementor doesn't need to know, you can use forward generic for that.
func foo<T: Foo>(_: T) { ... }
foo(4)
So implementor of foo doesn't know what T is, only that the user supply something that conforms to Foo.
If the user doesn't need to know, you can use reverse generic.
func foo() -> some Foo { ... }
let a = foo()
Then the user won't know what the type of a is, just that it conforms to Foo.
If both sides know what T is, they can just use concrete type.
If neither side knows what T is, well, that'd be bad.
All the concrete types must be decided somewhere along the line to instantiate the variables and pass them around. That also apply to the generic struct, class, etc.
They're not some tools to silent the compiling error.
You description seems to lean toward the first case, which I already suggested the syntax above.