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

Type member appears in java generic signature (this breaks graal native and won't make javac happy either) #15091

Closed
arixmkii opened this issue May 3, 2022 · 1 comment · Fixed by #15093

Comments

@arixmkii
Copy link
Contributor

arixmkii commented May 3, 2022

Compiler version

3.1.2

Minimized code

package io.github.arixmkii

import MyTypes.*

object Main extends MyInstances {

  def method[F[_], A](implicit F: Empty[F]): A = ???

  def main(args: Array[String]): Unit = {
    method[WrappedF[Id, *], Unit]
  }

}

object MyTypes {
  // Id effect
  type Id[A] = A

  // The most basic typeclass
  trait Empty[F[_]]

  // Empty wrapped effect type and related impl
  sealed abstract class WrappedFImpl {
    type T[F[_], A]
  }

  type WrappedF[F[_], A] = instance.T[F, A]

  val instance: WrappedFImpl = new WrappedFImpl {
    type T[F[_], A] = F[A]
  }
}

trait MyInstances {

  implicit def forWrappedF[F[_]]: Empty[WrappedF[F, *]] =
    new Empty[WrappedF[F, *]] {}
}

The full demo project (with compile and native image build for Scala 2 and 3) is here.

Output

It compiles with scalac -unchecked -deprecation -feature -language:implicitConversions -Ykind-projector, but when GraalVM native image build is called on the bytecode it results in exception:

Fatal error: java.lang.TypeNotPresentException: Type io.github.arixmkii.MyTypes$WrappedFImpl.T not present
  | => fat java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:117)
	at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:125)
	at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
	at java.base/sun.reflect.generics.visitor.Reifier.reifyTypeArguments(Reifier.java:68)
	at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:138)
	at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
	at java.base/sun.reflect.generics.repository.MethodRepository.computeReturnType(MethodRepository.java:75)
	at java.base/sun.reflect.generics.repository.MethodRepository.getReturnType(MethodRepository.java:66)
	at java.base/java.lang.reflect.Method.getGenericReturnType(Method.java:295)
	at com.oracle.svm.reflect.hosted.ReflectionDataBuilder.registerTypesForMethod(ReflectionDataBuilder.java:483)
	at com.oracle.svm.reflect.hosted.ReflectionDataBuilder.processMethodMetadata(ReflectionDataBuilder.java:284)
	at com.oracle.svm.reflect.hosted.ReflectionDataBuilder.duringAnalysis(ReflectionDataBuilder.java:185)
	at com.oracle.svm.reflect.hosted.ReflectionFeature.duringAnalysis(ReflectionFeature.java:189)
	at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$10(NativeImageGenerator.java:726)
	at com.oracle.svm.hosted.FeatureHandler.forEachFeature(FeatureHandler.java:74)
	at com.oracle.svm.hosted.NativeImageGenerator.lambda$runPointsToAnalysis$11(NativeImageGenerator.java:726)
	at com.oracle.graal.pointsto.PointsToAnalysis.runAnalysis(PointsToAnalysis.java:751)
	at com.oracle.svm.hosted.NativeImageGenerator.runPointsToAnalysis(NativeImageGenerator.java:723)
	at com.oracle.svm.hosted.NativeImageGenerator.doRun(NativeImageGenerator.java:558)
	at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:515)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:407)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:585)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:128)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner$JDK9Plus.main(NativeImageGeneratorRunner.java:615)
Caused by: java.lang.ClassNotFoundException: io.github.arixmkii.MyTypes$WrappedFImpl.T
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:587)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:467)
	at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeNamedType(CoreReflectionFactory.java:114)
	... 23 more

Expectation

Native image is generated successfully as it is for the same code with Scala 2.13.8 and old kind-projector plugin.

Additional notes

It is not clear if this is something, which should be addressed in dotty, but taking into account that native image is working on the generated bytecode it may be. If this is not for dotty team, then may be the team can add comments for GraalVM developers in this issue oracle/graal#4530 to help them.

Also, it is only my assumption that this is kind projector related as I didn't manage to minimize that code below, what is shown here.

@arixmkii arixmkii added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels May 3, 2022
@smarter
Copy link
Member

smarter commented May 3, 2022

The problem is that type members appear in generic type signatures:

% javap MyInstances.class
Compiled from "i15091.scala"
public interface io.github.arixmkii.MyInstances {
  public static io.github.arixmkii.MyTypes$Empty forWrappedF$(io.github.arixmkii.MyInstances);
  public <F> io.github.arixmkii.MyTypes$Empty<io.github.arixmkii.MyTypes$WrappedFImpl.T> forWrappedF();
}

io.github.arixmkii.MyTypes$WrappedFImpl.T is a type member and not a type parameter, so we should erase it from the generic java signature we generate in https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala

@smarter smarter changed the title kind-projector generate less reflective info than Scala 2 and fails with GraalVM native image Type member appears in java generic signature (this breaks graal native and won't make javac happy either) May 3, 2022
@smarter smarter added compat:java and removed stat:needs triage Every issue needs to have an "area" and "itype" label labels May 3, 2022
smarter added a commit to dotty-staging/dotty that referenced this issue May 3, 2022
smarter added a commit to dotty-staging/dotty that referenced this issue May 3, 2022
smarter added a commit to dotty-staging/dotty that referenced this issue May 3, 2022
- The PolyType case was dead code imported from Scala 2
- The HKTypeLambda case was correct for eta-expanded classes
  (e.g. in t7932 `Category[Tuple2]` should get as signature
  `Category<scala.Tuple2>`), but not for other type lambdas
  where it could lead to type members appearing in the signature.
  Fixed by splitting the case into an EtaExpansion case and
  a case for all other HKTypeLambdas (which are just replaced
  by a wildcard).

Fixes scala#15091.
bishabosha pushed a commit to dotty-staging/dotty that referenced this issue Oct 18, 2022
- The PolyType case was dead code imported from Scala 2
- The HKTypeLambda case was correct for eta-expanded classes
  (e.g. in t7932 `Category[Tuple2]` should get as signature
  `Category<scala.Tuple2>`), but not for other type lambdas
  where it could lead to type members appearing in the signature.
  Fixed by splitting the case into an EtaExpansion case and
  a case for all other HKTypeLambdas (which are just replaced
  by a wildcard).

Fixes scala#15091.
@Kordyjan Kordyjan added this to the 3.2.0 milestone Aug 1, 2023
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