I'm trying to understand why can't the Scala compiler infer the following restriction on a path-dependent type:
trait MyTrait
class MyTraitImpl extends MyTrait
trait MyTrait2[A <: MyTrait] {
type MyTraitType = A
}
class MyTrait2Impl[A <: MyTrait] extends MyTrait2[A]
val obj: MyTrait2[_] = new MyTrait2Impl[MyTraitImpl]
def myMethod[A <: MyTrait](t2: MyTrait2[A]) = println("Hi!")
myMethod[obj.MyTraitType](obj)
// <console>:14: error: type arguments [obj.MyTraitType] do not conform to method myMethod's type parameter bounds [A <: MyTrait]
// myMethod[obj.MyTraitType](obj)
For me, intuitively, MyTraitType can't be anything other than a subclass of a MyTrait, as the bound is right on A in MyTrait2. If there is, can you give me an example or point me to where this code snippet is wrong?
If this is a Scala compiler limitation, can anyone show me a way to achieve this using the type system? Note that:
- I do not have a
MyTraitobject, nor doesmyMethodreceive one; - I do not need
myMethodto know the concrete type ofA; all it needs to know is thatAit is a subtype ofMyTraitand thatt2is parametrized onA; - The underscore in
objis intentional; where I callmyMethod, I don't know the concrete type ofA(or else it would not be a problem); - I prefer solutions where I don't have to modify
myMethod.
You should just use constraints on type member instead of bounds on type parameter in
MyTrait2declaration:You'll get a compilation error on wrong types, just as expected:
Proof it works with
List[MyTrait2]: