luontola/retrolambda

java.lang.VerifyError: Bad operand type when invoking <init>

pietrodev opened this issue · 2 comments

This is quite easy to reproduce. I created the smallest possible test set

So, I have two classes, in the first one I have a singleton (for the test the instance is not stored but it doesn't matter now) and, for some reason, I use a supplier to create the instance. This test works well if the supplier is created as an inner class or with lambda. It crashes when using the method reference (::new).

public class Test1 {

  Test1() {}

  static Test1 get() {
    Supplier<Test1> s = Test1::new;
    return s.get();
  }

  interface Supplier<E> {
    E get();
  }
}

So there's a simple method get who creates the instance by using Test1::new method reference.

Then there's a second class who calls the get():

public class Test2 {
  public static void main(String[] args) {
    Test1.get();
  }
}

When compiled with retrolambda, bytecode 51, and executed, the output is

Exception in thread "main" java.lang.VerifyError: Bad operand type when invoking
Exception Details:
Location:
Test1.access$lambda$0(LTest1;)V @1: invokespecial
Reason:
Invalid type: 'Test1' (current frame, stack[0])
Current Frame:
bci: @1
flags: { }
locals: { 'Test1' }
stack: { 'Test1' }
Bytecode:
0x0000000: 2ab7 001f b1
at Test2.main(Test2.java:4)

I tested with latest retrolambda 2.0.3 compiled with java 1.8.0_45

Thanks for the detailed bug report. I'll look into this probably next week.

This is fixed in Retrolambda 2.0.4