Skip to content
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

Tuple specialisation doesn't correctly see type #18638

Closed
klaeufer opened this issue Oct 2, 2023 · 2 comments · Fixed by #18724
Closed

Tuple specialisation doesn't correctly see type #18638

klaeufer opened this issue Oct 2, 2023 · 2 comments · Fixed by #18724

Comments

@klaeufer
Copy link

klaeufer commented Oct 2, 2023

Compiler version

Welcome to Scala 3.3.1 (17.0.8.1, Java OpenJDK 64-Bit Server VM).

Minimized code

type U[H, T] = (Unit, Unit)

(((), ()): U[Int, Int]) match
  case ((), ()) => println("ok")

Output

java.lang.ClassCastException: class scala.runtime.BoxedUnit cannot be cast to class java.lang.Integer (scala.runtime.BoxedUnit is in unnamed module of loader java.net.URLClassLoader @5eefa415; java.lang.Integer is in module java.base of loader 'bootstrap')

Expectation

  • Should print "ok".
  • Should behave the same as when unannotated or annotated with result of manually applying type alias to parameters:
(((), ()): (Unit, Unit)) match
  case ((), ()) => println("ok")
ok

Additional observations

  • This problem did not occur in Scala 3.1.x, and I first observed it in Scala 3.2.0.
  • The problem seems to occur only for Tuple2 and 2-ary type aliases.
  • The problem occurs for two, not necessary equal, integer-based actual type parameters: Boolean, Char, Int, Long
  • It doesn't matter what the concrete tuple element types are, as long as at least one of them is different from the corresponding actual type parameter.
  • It doesn't make a difference if the type parameters are actually used, e.g.,
    type ListNodeF[H, T] = (H, Option[T])
@klaeufer klaeufer added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 2, 2023
@bishabosha bishabosha added area:transform and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels Oct 16, 2023
@bishabosha
Copy link
Member

Looks like a problem in compiler/src/dotty/tools/dotc/transform/SpecializeTuples.scala:40

@bishabosha bishabosha changed the title 2-ary type alias for Tuple2 can cause ClassCastException (confusion between type parameter and element type of tuple) Tuple specialisation doesn't correctly see type Oct 16, 2023
@nicolasstucki nicolasstucki self-assigned this Oct 19, 2023
@nicolasstucki
Copy link
Contributor

Minimization

type U[H, T] = (Unit, Unit)
def test1(u: U[Int, Int]) = u._1
def test2(u: (Unit, Unit)) = u._1

Compiled with -Xprint:specializeTuples:

package <empty> {
  final lazy module val Test$package: Test$package = new Test$package()
  @SourceFile("t/Test.scala") final module class Test$package() extends Object()
     {
    private def writeReplace(): AnyRef =
      new scala.runtime.ModuleSerializationProxy(classOf[Test$package.type])
    type U = [H, T] =>> (Unit, Unit)
    def test1(u: U[Int, Int]): Unit = u._1$mcI$sp // issue here
    def test2(u: (Unit, Unit)): Unit = u._1
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants