In this article, it is explained that each generic type argument in Scala 3 code is perceived as a dependent type to be conform with the DOT logic:
https://dotty.epfl.ch/docs/internals/higher-kinded-v2.html
Namely:
The duality The core idea: A parameterized class such as
class Map[K, V]
is treated as equivalent to a type with type members:
class Map { type Map$K; type Map$V }
(the article may be obsolete but the design philosophy should still hold)
Consequentially, I would expect any contravariant & covariant modifiers for type arguments are also rewritten, so I did a quick experiment, the compiler should be able to convert the following code:
object AsArg {
trait P[+TT] {
val vv: TT
}
trait P1 extends P[Product] {
val vv: Product
}
trait P2 extends P1 with P[Tuple1[Int]] {
val vv: Tuple1[Int]
}
}
into this:
object AsDependentType {
trait P {
type TT
val vv: TT
}
trait P1 extends P {
type TT <: Product
val vv: Product
}
trait P2 extends P1 with P {
type TT <: Tuple1[Int]
val vv: Tuple1[Int]
}
}
Ironically, after conversion, the compiler throw the following errors:
[Error] ...CovariantDependentType.scala:30:11: error overriding value vv in trait P of type P1.this.TT;
value vv of type Product has incompatible type
[Error] ...CovariantDependentType.scala:36:11: error overriding value vv in trait P of type P2.this.TT;
value vv of type Tuple1[Int] has incompatible type
two errors found
So what is the correct equivalent code after conversion?