I stumbled upon a puzzling behaviour of Type.=:=
when applied on type refinments.
Consider:
import reflect.runtime.universe._
type T1 = AnyRef {
def apply( name: String ): Unit
def foo: String
}
type Base = { def apply( name: String ): Unit }
type T2 = Base {
def foo: String
}
Given that Base
is an alias for a type refinement, I would expected that refining it further by adding the member foo
would
yield the same type as if I had defined foo
right in Base
.
Or in other words, I would expect that T1
and T2
denote entirely equivalent types.
For the most part, scalac seems to agree.
By example I can pass an instance of T2
where an instance of T1
is expected:
def f( x: T1 ){}
f( null: T2 ) // scalac does not complain here
And conversely:
def g( x: T2 ){}
g( null: T1 ) // scalac is still happy
I can also ask for an evidence T1 =:= T2
and it compiles fine too:
implicitly[T1 =:= T2]
However, using scala reflection I get entirely different results:
scala> typeOf[T1] =:= typeOf[T2]
res2: Boolean = false
So is this a scala reflection bug (I would guess so) or is there a fundamental reason (technical of otherwise) why typeOf[T1] =:= typeOf[T2]
would return false?
typeOf[T1] <:< typeOf[T2]
and conversely are also true. – som-snytt(typeOf[T1] <:< typeOf[T2]) && (typeOf[T2] <:< typeOf[T1])
. Obviously this still feels like a hack though – Régis Jean-Gilles