I'm a bit perplexed by the strictness of the typechecker below — it seems that the invariant T position of Inv[T] is also invariant within Variantish's parameter list:
scala> class Inv[T]
defined class Inv
scala> class Variantish[+T, +TVar <: Inv[T]]
<console>:12: error: covariant type T occurs in invariant position in type  <: Inv[T] of type TVar
       class Variantish[+T, +TVar <: Inv[T]]
                             ^
Variant types can normally occur in what look like invariant argument-list positions legally, e.g. with object-protected visibility:
class Variantish[+T](protected[this] var v: Inv[T])
and it seems that the following would be just as typesafe:
class Variantish[+T, +TVar <: Inv[T]](protected[this] var v: TVar)
Need that check mentioned above be so strict?
From the language specification (emphasis mine), about conformance (ie T' is a super-type of T): 
Type constructors
TandT′follow a similar discipline. We characterizeTandT′by their type parameter clauses[a1,…,an]and[a′1,…,a′n], where anaiora′imay include a variance annotation, a higher-order type parameter clause, and bounds. Then,Tconforms toT′if any list[t1,…,tn]-- with declared variances, bounds and higher-order type parameter clauses -- of valid type arguments forT′is also a valid list of type arguments forTandT[t1,…,tn]<:T′[t1,…,tn].
This is really difficult to understand (IMHO), but I believe it means that for Variantish to be covariant in T, you would have to be able to write
Variantish[Dog, TVar] <: Variantish[Animal, TVar]
for any TVar for which Variantish[Animal, TVar] makes sense. But this doesn't even make sense (let alone have any truth value) for some of those TVar, such as Inv[Animal]. That's why it is forbidden in that place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With