google / j2cl

Java to Closure JavaScript transpiler
Apache License 2.0
1.23k stars 144 forks source link

Generic types can't be iterated using a for-each loop #140

Closed niloc132 closed 2 years ago

niloc132 commented 2 years ago

Describe the bug Attempt to compile this class (the helloworld sample can be modified easily to use this):

public class HelloWorld {

  public static <T, C extends Collection<T>> String getHelloWorld(C values) {
    for (T value : values) {
      return value.toString();
    }
    return "no values";
  }
}

To Reproduce Edit samples/helloworld/src/main/java/com/google/j2cl/samples/helloworldlib/HelloWorld.java to have a method like the one above - it isn't important that the code will pass through closure successfully to be able to reproduce this.

Build in samples/helloworld, such as bazel build //....

for (T value : values) {
  return value.toString();
}

        ... 35 more
Caused by: java.lang.ClassCastException: class com.google.j2cl.transpiler.ast.AutoValue_TypeVariable cannot be cast to class com.google.j2cl.transpiler.ast.DeclaredTypeDescriptor (com.google.j2cl.transpiler.ast.AutoValue_TypeVariable and com.google.j2cl.transpiler.ast.DeclaredTypeDescriptor are in unnamed module of loader 'app')
        at com.google.j2cl.transpiler.ast.TypeDescriptor.toBoxedType(TypeDescriptor.java:149)
        at com.google.j2cl.transpiler.passes.NormalizeForEachStatement.maybeAddCast(NormalizeForEachStatement.java:260)
        at com.google.j2cl.transpiler.passes.NormalizeForEachStatement.convertForEachIterable(NormalizeForEachStatement.java:183)
        at com.google.j2cl.transpiler.passes.NormalizeForEachStatement.access$100(NormalizeForEachStatement.java:43)
        at com.google.j2cl.transpiler.passes.NormalizeForEachStatement$1.rewriteForEachStatement(NormalizeForEachStatement.java:62)
        at com.google.j2cl.transpiler.passes.NormalizeForEachStatement$1.rewriteForEachStatement(NormalizeForEachStatement.java:54)
        at com.google.j2cl.transpiler.ast.AbstractRewriter.postProcessForEachStatement(AbstractRewriter.java:383)
        at com.google.j2cl.transpiler.ast.Visitor_ForEachStatement.visit(Visitor_ForEachStatement.java:22)
        ... 34 more

Bug is present in current HEAD, going back at least as far as 3c97afeacbc4b7838c231205e979629c85cd5b33.

Bazel version Please include version of Bazel that you are running J2CL with: $ bazel version Bazelisk version: v1.7.4 Build label: 4.2.2 Build target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar Build time: Thu Dec 2 18:15:58 2021 (1638468958) Build timestamp: 1638468958 Build timestamp as int: 1638468958

Expected behavior This code should compile correctly.

Workaround Cast the collection before looping:

for (T value : (Collection<T>)values) {