Open
Description
reproduction steps
using Scala 2.13.4
-
Whole PoC code is https://gist.github.com/y-yu/2c5ff872b22acde4e1b3685a8ae015e8
- Execute
sbt run
after download the files
- Execute
-
There is a type erasing difference between two classes:
B1
andB1
package example trait A[B[_]] class B1(x: String, y: A[List]) class B2(x: String)(y: A[List])
- class
B2
defined to take two parameters as multiple parameter lists
- class
-
Their
javap
results are:$ javap target/scala-2.13/classes/example/B1.class Compiled from "Main.scala" public class example.B1 { public example.B1(java.lang.String, example.A<scala.collection.immutable.List>); } $ javap target/scala-2.13/classes/example/B2.class Compiled from "Main.scala" public class example.B2 { public example.B2(java.lang.String, example.A<?>); }
- In
B2
constructor, the type of the second argument is the erasured type:A<?>
- In
-
We expect that
B1
andB2
should be the same result
problem
- We found this bihavior using Google Guice
- Needless to say, it's very popular library
- We use this for Play framework
- This behavior is not good for DI wiring higer-kinded classes by Guice
- We cannot use currying constructor if the constructor takes higher-kinded type arguments such like
Monad
instance - Since using Guice DI, we have to inject only our classes but also
implicit
parameters 😢
- We cannot use currying constructor if the constructor takes higher-kinded type arguments such like
- So we wish to resolve this bihavior 🙏
postscript
- We pass the higher-kinded type parameter like this:
class B3[F[_]](x: String)(y: A[F])
- It's OK 🙆♀️ but I don't know why it was not erased 🤔
$ javap -c example.B3 Compiled from "Main.scala" public class example.B3<F> { public example.B3(java.lang.String, example.A<F>); }
- @xuwei-k san tried it out in Scala3.0.0-M1
$ javap target/scala-3.0.0-M1/classes/example/B1.class Compiled from "Main.scala" public class example.B1 { public example.B1(java.lang.String, example.A<scala.collection.immutable.List<java.lang.Object>>); } $ javap target/scala-3.0.0-M1/classes/example/B2.class Compiled from "Main.scala" public class example.B2 { public example.B2(java.lang.String, example.A<scala.collection.immutable.List<java.lang.Object>>); }
- Why is
java.lang.Object
inserted as their type arguments? 🤔 - Anyway both cases don't work well in Scala3.0.0-M1
- Would it be better to report this to dotty repo too?
- Why is