Skip to content

Specialization is sensitive to names of type parameters #11845

@mbuzdalov

Description

@mbuzdalov

The following code snippet compiles fine, as intended, but fails at runtime with a class cast exception.

object Main {
  trait Two[@specialized C, @specialized F] {
    def trouble(p: Int): C
  }

  class Instance(val p: Int) extends Two[Long, Int] {
    override def trouble(p: Int): Long = 0
  }

  // in this trait, and only here, "C" is actually a cyrillic "С"
  trait Entry {
    def call[@specialized С, @specialized F](a: Two[С, F]): Unit
  }

  object SimpleEntry extends Entry {
    def call[@specialized C, @specialized F](a: Two[C, F]): Unit =
      a.trouble(0)
  }

  def main(args: Array[String]): Unit = {
    SimpleEntry.call(new Instance(0))

    val algorithm: Entry = SimpleEntry
    algorithm.call(new Instance(0))
  }
}

More precisely, it runs well when the optimize method is called on SimpleOptimizer directly, but when it is called on a trait, it fails with the following stack trace:

(scala 2.12.4)

java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
        at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:101)
        at Main$Two.trouble$mcI$sp(Main.scala:3)
        at Main$Two.trouble$mcI$sp$(Main.scala:3)
        at Main$Instance.trouble$mcI$sp(Main.scala:6)
        at Main$SimpleEntry$.call$mIJc$sp(Main.scala:17)
        at Main$.main(Main.scala:24)
        at Main.main(Main.scala)
        ...

(scala 2.13.1)

Exception in thread "main" java.lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
	at scala.runtime.BoxesRunTime.unboxToInt(BoxesRunTime.java:99)
	at Main$Two.trouble$mcI$sp(Main.scala:3)
	at Main$Two.trouble$mcI$sp$(Main.scala:3)
	at Main$Instance.trouble$mcI$sp(Main.scala:6)
	at Main$SimpleEntry$.call$mIJc$sp(Main.scala:17)
	at Main$.main(Main.scala:24)
	at Main.main(Main.scala)

From this stack trace, one can see that in this particular piece:

	at Main$Instance.trouble$mcI$sp(Main.scala:6)

the type of the type argument, mcI is wrong, as it shall be mcJ for Long. What is more, the immediate caller:

	at Main$SimpleEntry$.call$mIJc$sp(Main.scala:17)

seems to be wrong as well, as the investigation of the stack trace of the successful direct call in the debugger shows the mJIc in the signature.

Replacing the Cyrillic type parameter С with a Latin C gets everything to the place.

Scala version: 2.12.4, 2.13.1
Java version: openjdk version "1.8.0_232"

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions