Skip to content

java.util.Collections.min has wrong return type #7963

Closed
@molikto

Description

@molikto

minimized code

abstract class Test extends java.lang.Comparable[Test] {

  def test: Unit = {
  	java.util.Collections.min(new java.util.ArrayList[Test]())
  }
}
Compilation output
public abstract class Test extends java.lang.Object implements java.lang.Comparable<Test>
  minor version: 0
  major version: 52
  flags: (0x0421) ACC_PUBLIC, ACC_SUPER, ACC_ABSTRACT
  this_class: #2                          // Test
  super_class: #5                         // java/lang/Object
  interfaces: 1, fields: 0, methods: 2, attributes: 4
Constant pool:
   #1 = Utf8               Test
   #2 = Class              #1             // Test
   #3 = Utf8               Ljava/lang/Object;Ljava/lang/Comparable<LTest;>;
   #4 = Utf8               java/lang/Object
   #5 = Class              #4             // java/lang/Object
   #6 = Utf8               java/lang/Comparable
   #7 = Class              #6             // java/lang/Comparable
   #8 = Utf8               test.scala
   #9 = Utf8               <init>
  #10 = Utf8               ()V
  #11 = NameAndType        #9:#10         // "<init>":()V
  #12 = Methodref          #5.#11         // java/lang/Object."<init>":()V
  #13 = Utf8               this
  #14 = Utf8               LTest;
  #15 = Utf8               test
  #16 = Utf8               java/util/ArrayList
  #17 = Class              #16            // java/util/ArrayList
  #18 = Methodref          #17.#11        // java/util/ArrayList."<init>":()V
  #19 = Utf8               java/util/Collections
  #20 = Class              #19            // java/util/Collections
  #21 = Utf8               min
  #22 = Utf8               (Ljava/util/Collection;)Ljava/lang/Comparable;
  #23 = NameAndType        #21:#22        // min:(Ljava/util/Collection;)Ljava/lang/Comparable;
  #24 = Methodref          #20.#23        // java/util/Collections.min:(Ljava/util/Collection;)Ljava/lang/Comparable;
  #25 = Utf8               Code
  #26 = Utf8               LineNumberTable
  #27 = Utf8               LocalVariableTable
  #28 = Utf8               Signature
  #29 = Utf8               SourceFile
  #30 = Utf8               TASTY
  #31 = Utf8               Scala

expectation

the return type should be Object, but instead is Ljava/lang/Comparable


See comment bellow for more information where it is wrong.

After trying to fix this problem, I found the root cause is in ClassfileParser, all type bounds is eagerly & in sig2typeBounds, so this is not a bug in erasure or backend.

I cannot think of a proper way to overcame this now. Maybe we should also parse the erasured signature from constant pool, then in Erasure we will always use the ones parsed instead compute ourselves?

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions