javac doesn't generate the correct bytecode for lambda if the target type is an intersection type

forax at univ-mlv.fr forax at univ-mlv.fr
Thu Nov 5 10:12:42 UTC 2015


----- Mail original -----
> De: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>, compiler-dev at openjdk.java.net
> Envoyé: Jeudi 5 Novembre 2015 10:47:59
> Objet: Re: javac doesn't generate the correct bytecode for lambda if the target type is an intersection type
> 
> Thanks for the report - looks an interesting issue; I also note that a
> MethodHandle.asType adaptation would have solved this issue?

yes, right.
at runtime, an intersection type is a class that implements all the types so asType() works here
and you can do that for any reference which has an interface as declaring type.
I don't think it's a good idea to try to replace the check which is done during linking time (invokedynamic linking time)
to a check done at runtime. If something bark at linking time it's usually a bug in javac (or a separate compilation issue).

> 
> Maurizio

Rémi

> 
> On 05/11/15 09:37, Remi Forax wrote:
> > About this bug,
> >    https://bugs.openjdk.java.net/browse/JDK-8141508
> >
> > javac has trouble with intersection type that are target type of a lambda
> > and method reference,
> > Usually when there is an intersection type, javac substitute it by the
> > first type of the intersection type and add cast when necessary.
> >
> > Let suppose we have this code,
> >
> > public class Intersection {
> >    interface I {
> >    }
> >    interface J {
> >      void foo();
> >    }
> >
> >    static <T extends I & J> void bar(T t) {
> >        Runnable r = t::foo;
> >    }
> >    
> >    public static void main(String[] args) {
> >      class A implements I, J { public void foo() {} }
> >      bar(new A());
> >    }
> > }
> >
> >
> > Currently, javac generates a method reference on J::foo with an
> > invokedynamic that takes an I as parameter, hence it fails at runtime.
> > javac should de-sugar t::foo into a lambda that take an I and then add a
> > cast to J like for a call to a method of an intersection type.
> >
> > So the workaround is to use a lambda instead,
> >    Runnable r = t -> t.foo();
> >
> > I've already seen this bug somewhere but was not able to find a
> > corresponding bug report in the database :(
> >
> > cheers,
> > Rémi
> >
> >   
> 
> 


More information about the compiler-dev mailing list