Skip to content

Invalid generic signature for type params bounded by primitive #15385

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

Closed
scf37 opened this issue Jun 6, 2022 · 3 comments · Fixed by #16442
Closed

Invalid generic signature for type params bounded by primitive #15385

scf37 opened this issue Jun 6, 2022 · 3 comments · Fixed by #16442
Assignees
Labels
Milestone

Comments

@scf37
Copy link

scf37 commented Jun 6, 2022

Compiler version

3.1.6

Minimized code

def foo[A <: Int]: A = ???

Output

public <A> A foo() {
    throw Predef$.MODULE$.$qmark$qmark$qmark();
}

Expectation

public int foo() {
    throw Predef$.MODULE$.$qmark$qmark$qmark();
}

It is important for performance of code dealing with types carrying meta-information like

type Validated[A] = A
opaque type Max[A, max] <: A with Validated[A] = A
@scf37 scf37 added itype:bug stat:needs triage Every issue needs to have an "area" and "itype" label labels Jun 6, 2022
@nicolasstucki
Copy link
Contributor

That example seems to compile using the primitive type. Though a slightly different example does not.

class Foo:
  def foo[A <: Int]: A = ???
  def bar[A <: Int](a: A): A = ???
public class Foo {
  public Foo();
  public int foo();
  public <A> A bar(A);
}

@nicolasstucki nicolasstucki added area:erasure itype:enhancement and removed stat:needs triage Every issue needs to have an "area" and "itype" label itype:bug labels Jun 8, 2022
@smarter
Copy link
Member

smarter commented Jun 8, 2022

Both of the methods here haveA erased to Int (see the descriptor in the output of javap), the problem is that the generic java signature we generate for bar is incorrect (this is what javap uses to display the method signature but it's not the actual bytecode signature, it's only used by javac), A shouldn't be preserved in Signature when its upper-bound is a primitive type:

% javap -p -v Foo.class
[...]
  public int foo();
    descriptor: ()I
[...]
  public <A extends java.lang.Object> A bar(A);
    descriptor: (I)I
[...]
    Signature: #28                          // <A:Ljava/lang/Object;>(TA;)TA;
[...}

The same bug exists in Scala 2: scala/bug#9846

For anyone interested in working on this, the generic signature logic is in https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/transform/GenericSignatures.scala

@smarter smarter changed the title Complex types bound to primitives should compile to primitive types Invalid generic signature for type params bounded by primitive Jun 8, 2022
@odersky odersky added the Spree Suitable for a future Spree label Jun 12, 2022
@scala-center-bot
Copy link

This issue was picked for the Issue Spree No. 24 of 29 November 2022 which takes place in a week from now. @jan-pieter, @nmcb, @TheElectronWill will be working on it. If you have any insight into the issue or guidance on how to fix it, please leave it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants