Skip to content

Unexpected erasure of opaque type with parameter #6159

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
panacekcz opened this issue Mar 25, 2019 · 4 comments
Closed

Unexpected erasure of opaque type with parameter #6159

panacekcz opened this issue Mar 25, 2019 · 4 comments
Assignees

Comments

@panacekcz
Copy link
Contributor

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

@OlivierBlanvillain
Copy link
Contributor

I am under the impression than all of this is working as intended. Can you point to a specific part of the sip which suggests that this should be otherwise?

@sjrd
Copy link
Member

sjrd commented Mar 25, 2019

Opaque type aliases are definitely expected to always erase exactly like a normal type alias would. So any discrepancy between an opaque type alias and a transparent one, at erasure level, is a bug.

@OlivierBlanvillain
Copy link
Contributor

Makes sense. Does this entirely invalidates the encoding implemented in #5300?

@sjrd
Copy link
Member

sjrd commented Mar 25, 2019

Not at the level of typer. But some later phase should make sure that erasure can actually see through the aliases. (or erasure itself should force itself to see through opaque type aliases)

@odersky odersky self-assigned this Mar 25, 2019
odersky added a commit to dotty-staging/dotty that referenced this issue Mar 25, 2019
@odersky odersky closed this as completed in b586d9b Apr 2, 2019
odersky added a commit that referenced this issue Apr 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants