Closed
Description
Outside its companion, opaque type defined using its type parameter erases to the bound of the parameter, not the actual type argument.
That is different from normal type alias and can lead to boxing of values or overloading errors.
Code:
trait A
trait B extends A
object O{
opaque type T[X <: A] = X
type U[X <: A] = X
object T{
def t(a: T[B]): T[B] = a
def u(a: U[B]): U[B] = a
}
def t(a: T[B]): T[B] = a
def u(a: U[B]): U[B] = a
}
With -Xprint:erasure
:
... class T$ ... { ...
def t(a: B): B = a
def u(a: B): B = a
}
def t(a: A): A = a
def u(a: B): B = a ...
Boxing
object O{
opaque type T[X] = X
object T{
def wrap(a: Int): T[Int] = a
def unwrap(a: T[Int]): Int = a
}
def w(a: Int): T[Int] = T.wrap(a)
def u(a: T[Int]): Int = T.unwrap(a)
}
With -Xprint:erasure
:
... def w(a: Int): Object = scala.Int.box(O.T.wrap(a))
def u(a: Object): Int = O.T.unwrap(scala.Int.unbox(a)) ...
Overloading
object O{
opaque type T[X] = X
def m(a: T[Int]) = 1
def m(a: T[String]) = 2
}
Output:
-- [E120] Duplicate Symbol Error: opaque-overload.scala:6:6 --------
6 | def m(a: T[String]) = 2
| ^
| Double definition:
| def m(a: O.T.T[Int]): Int in object O at line 5 and
| def m(a: O.T.T[String]): Int in object O at line 6
| have the same type after erasure.
one error found
Metadata
Metadata
Assignees
Labels
No labels