Skip to content

Generic signature replaces bounded method type parameter uses with the enclosing class type #26531

Description

@He-Pin

Compiler version

  • 3.9.0-RC2
  • 3.9.0-RC3
  • 3.10.0-RC1-bin-20260712-f51c618-NIGHTLY

The same code works with 3.8.3 and 3.9.0-RC1, so the regression starts in 3.9.0-RC2.

Minimized code

Repro.scala:

package repro

import java.util.function.Consumer

final class Builder[T] {
  def accept[M <: T](clazz: Class[M], consumer: Consumer[M]): Unit = ()
}

Use.java:

package repro;

final class Use {
  interface Command {}
  static final class Create implements Command {}

  void test(Builder<Command> builder) {
    builder.accept(Create.class, (Create command) -> {});
  }
}

Compile with:

scala-cli compile Repro.scala -S 3.9.0-RC3 --server=false -d out
javac -cp out -d out Use.java

Output

Use.java:8: error: incompatible types: Class<Create> cannot be converted to Class<Command>
    builder.accept(Create.class, (Create command) -> {});
                         ^

javap -p -s repro.Builder shows that the method type parameter M is declared, but all of its uses are replaced with the outer type parameter T:

public <M extends T> void accept(java.lang.Class<T>, java.util.function.Consumer<T>);

With 3.8.3 and 3.9.0-RC1, the generated signature is:

public <M extends T> void accept(java.lang.Class<M>, java.util.function.Consumer<M>);

Expectation

The method type variable M has upper bound T, but it remains a distinct type variable. Its occurrences in Class[M] and Consumer[M] must therefore be encoded as M, as they were before 3.9.0-RC2. Java should be able to infer M = Create and compile the call.

This breaks Java-facing generic APIs in Apache Pekko PR #3303, including BehaviorBuilder[T].onMessage[M <: T], where valid Java method references no longer compile. The affected compiler area overlaps the generic-signature rewrite in #25880.

Activity

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

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions