Skip to content

Illegal signature for higher kinded type with AnyVal upper bound #5720

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
Blaisorblade opened this issue Jan 15, 2019 · 7 comments
Closed

Illegal signature for higher kinded type with AnyVal upper bound #5720

Blaisorblade opened this issue Jan 15, 2019 · 7 comments

Comments

@Blaisorblade
Copy link
Contributor

While testing another patch, I got this output:

[info] Test dotty.tools.dotc.CompilationTests.fuzzyAll started
<B:J>Ljava/lang/Object;: ':' expected at index 4ted (115/146, 0 failed, 2s)
<B:J>()V: ':' expected at index 4
[=======================================] completed (146/146, 0 failed, 3s)

Grep suggests that might be coming from https://github.com/lampepfl/scala/blob/9ef70dd9b9eeec11cfb72dabb57c61198fa18a20/src/asm/scala/tools/asm/util/CheckClassAdapter.java#L993.

Noting this for future usage, can't investigate right now...

@nicolasstucki
Copy link
Contributor

tests/fuzzy/IAE-4a69457e1319217c3bac170110ea4ba58dca11a6.scala with the code

class A[B[_] <: Long]

is generating the waring

@nicolasstucki
Copy link
Contributor

Can be replicated with dotc tests/fuzzy/IAE-4a69457e1319217c3bac170110ea4ba58dca11a6.scala -Xverify-signatures

@nicolasstucki
Copy link
Contributor

nicolasstucki commented Jan 29, 2019

It seems to happen for any C <: AnyVal in class A[B[_] <: C]. It also seems impossible to provide a B satisfying this bounds, hence this could be rejected at definition site. @Blaisorblade WDYT?

@nicolasstucki nicolasstucki changed the title testCompilation fuzzing report Illegal signature for higher kinded type with AnyVal upper bound Jan 29, 2019
@Blaisorblade
Copy link
Contributor Author

@nicolasstucki Multiple such Bs exist, so it's a valid bug. The fix seems a one-liner.

I guess your point is that you can't extend Long, but you can still satisfy it in multiple ways — at least [x] => Long and [x] => Nothing are valid arguments (see below). And values classes aren't that special — we could forbid all bounds X <: T where T is a final class, but I don't like it.

Glancing at https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.9.1 reveals that <B:J>()V means, literally, <B <: Long>()void, which is illegal.
For class A[B <: Long], the upper bounds becomes java.lang.Object; but apparently the responsible code (in erasure?) misses higher kinds.

I found the responsible code and how to fix it for these cases. Thinking it through and testing a bit.

scala> class A[B[_] <: Long]
// defined class A

scala> type C = A[[x] => Long]
// defined alias type C = A[[x] => Long]

scala> type C = A[[x] => Nothing]
// defined alias type C = A[[x] => Nothing]

Blaisorblade added a commit to dotty-staging/dotty that referenced this issue Jan 29, 2019
In generic signature generator `jsig`, flag `primitiveOK` remembers if `jsig` is
allowed to output primitive types or not; for instance, upper bounds can't
contain primitive types. When transforming higher-kinded upper bounds `[X] =>
T`, `jsig` correctly recurs on `T`, but must remember flag `primitiveOK`.

The status of `toplevel` should not change either (since it tracks if are still
at the toplevel of the output signature, or instead we have started producing
output), so passing it seems safest. Ideally we should test it at least on
higher types whose body is a suitable `ClassInfo`; with polymorphic function
types, we should also test `PolyType` bodies.
@ghost ghost added the review label Jan 29, 2019
@Blaisorblade
Copy link
Contributor Author

@nicolasstucki Also, somehow this error does not fail the test in #5708 (which seems to use -Xverify-signatures). Should that be fixed? I can't investigate that now...

Blaisorblade added a commit to dotty-staging/dotty that referenced this issue Jan 29, 2019
In generic signature generator `jsig`, flag `primitiveOK` remembers if `jsig` is
allowed to output primitive types or not; for instance, upper bounds can't
contain primitive types. When transforming higher-kinded upper bounds `[X] =>
T`, `jsig` correctly recurs on `T`, but must remember flag `primitiveOK`.

The status of `toplevel` should not change either (since it tracks if are still
at the toplevel of the output signature, or instead we have started producing
output), so passing it seems safest. Ideally we should test it at least on
higher types whose body is a suitable `ClassInfo`; with polymorphic function
types, we should also test `PolyType` bodies.
@nicolasstucki
Copy link
Contributor

@Blaisorblade move the test to tests/neg

@Blaisorblade
Copy link
Contributor Author

Also, somehow this error does not fail the test in #5708 (which seems to use -Xverify-signatures).

Ah, that's because it's a normal error and we check for crashes, so I'd want -Xverify-signatures to crash there... or to move all those tests in neg as discussed... Well up to you.

@Blaisorblade Blaisorblade removed their assignment Jan 29, 2019
Blaisorblade added a commit to dotty-staging/dotty that referenced this issue Jan 29, 2019
In generic signature generator `jsig`, flag `primitiveOK` remembers if `jsig` is
allowed to output primitive types or not; for instance, upper bounds can't
contain primitive types. When transforming higher-kinded upper bounds `[X] =>
T`, `jsig` correctly recurs on `T`, but must remember flag `primitiveOK`.

The status of `toplevel` should not change either (since it tracks if are still
at the toplevel of the output signature, or instead we have started producing
output), so passing it seems safest. Ideally we should test it at least on
higher types whose body is a suitable `ClassInfo`; with polymorphic function
types, we should also test `PolyType` bodies.
Blaisorblade added a commit to dotty-staging/dotty that referenced this issue Jan 29, 2019
In generic signature generator `jsig`, flag `primitiveOK` remembers if `jsig` is
allowed to output primitive types or not; for instance, upper bounds can't
contain primitive types. When transforming higher-kinded upper bounds `[X] =>
T`, `jsig` correctly recurs on `T`, but must remember flag `primitiveOK`.

The status of `toplevel` should not change either (since it tracks if are still
at the toplevel of the output signature, or instead we have started producing
output), so passing it seems safest. Ideally we should test it at least on
higher types whose body is a suitable `ClassInfo`; with polymorphic function
types, we should also test `PolyType` bodies.
Blaisorblade added a commit to dotty-staging/dotty that referenced this issue Jan 30, 2019
In generic signature generator `jsig`, flag `primitiveOK` remembers if `jsig` is
allowed to output primitive types or not; for instance, upper bounds can't
contain primitive types. When transforming higher-kinded upper bounds `[X] =>
T`, `jsig` correctly recurs on `T`, but must remember flag `primitiveOK`.

The status of `toplevel` should not change either (since it tracks if are still
at the toplevel of the output signature, or instead we have started producing
output), so passing it seems safest. Ideally we should test it at least on
higher types whose body is a suitable `ClassInfo`; with polymorphic function
types, we should also test `PolyType` bodies.

Revised with tests requested in review.
nicolasstucki added a commit that referenced this issue Jan 30, 2019
Fix #5720: don't output X <: Long in Java generic signatures
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants