Intersection type and method ref bug ?

B. Blaser bsrbnd at gmail.com
Thu Oct 22 12:18:14 UTC 2020


Thanks for the pull request, Vicente.

However, it seems there are some failing tests. The patch looks
globally good but I saw you added the following lines to my initial
fix which don't look necessary:

@@ -2321,7 +2326,7 @@ Type generatedRefSig() {
             }

             Type bridgedRefSig() {
-                return
types.erasure(types.findDescriptorSymbol(tree.target.tsym).type);
+                return types.erasure(types.findDescriptorType(tree.target));
             }
         }
     }

So, I suggest you try to re-run the tests without the above change,
keeping the intent of my original fix which passes tier1 on jdk14u.

What do you think?
Bernard

On Wed, 21 Oct 2020 at 15:46, B. Blaser <bsrbnd at gmail.com> wrote:
>
> Yes, please.
> Feel free to push it and simply list me as contributor until I have
> some cycles to get acquainted with the new git process.
>
> Thanks!
> Bernard
>
> On Tue, 20 Oct 2020 at 22:06, Vicente Romero <vicente.romero at oracle.com> wrote:
> >
> > Hi Bernard,
> >
> > The patch looks good to me. Do you need help with the git PR?
> >
> > Vicente
> >
> > On 10/15/20 10:56 AM, B. Blaser wrote:
> > > Hi,
> > >
> > > Resurrecting this old thread as the following expression:
> > >
> > >      Stream.of(new A(), new B()).map(Test::f).forEach(System.out::println);
> > >
> > > still throws a LCE at runtime: "Type mismatch for lambda argument 0:
> > > class Test$C is not convertible to interface Test$I".
> > >
> > >  From 'Stream::of' we have 'Stream<C & I>' and then:
> > >
> > >      <R> Stream<R> map(Function<? super C & I, ? extends R> mapper);
> > >
> > > Further, wildcards are removed per JLS15 §9.9 resulting to the
> > > functional descriptor 'apply(C & I)' finally erased to 'apply(C)'
> > > which isn't convertible to 'lambda$main$0(Test$I)' that javac
> > > currently generates, failing to detect the intersection type 'C & I'.
> > >
> > > The following patch adds the missing lines to 'LambdaToMethod' on
> > > jdk14u (langtools:tier1 is OK).
> > >
> > > What do you think?
> > > Bernard
> > >
> > > diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
> > > b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
> > > --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
> > > +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java
> > > @@ -968,6 +968,10 @@
> > >                   // If the unerased parameter type is a type variable whose
> > >                   // bound is an intersection (eg. <T extends A & B>) then
> > >                   // use the SAM parameter type
> > > +                if (checkForIntersection && descPTypes.head.getKind()
> > > == TypeKind.INTERSECTION) {
> > > +                    parmType = samPTypes.head;
> > > +                }
> > > +
> > >                   if (checkForIntersection && descPTypes.head.getKind()
> > > == TypeKind.TYPEVAR) {
> > >                       TypeVar tv = (TypeVar) descPTypes.head;
> > >                       if (tv.getUpperBound().getKind() ==
> > > TypeKind.INTERSECTION) {
> > >
> > >
> > > On Fri, 26 Oct 2018 at 15:21, Vicente Romero <vicente.romero at oracle.com> wrote:
> > >> Hi Remi, Francois,
> > >>
> > >> Thanks for reporting this. I have created [1] to track this issue,
> > >>
> > >> Vicente
> > >>
> > >> [1] https://bugs.openjdk.java.net/browse/JDK-8213032
> > >>
> > >> On 10/24/18 6:05 AM, Remi Forax wrote:
> > >>> This bug was discovered by Francois Green when testing records, but the bug is independent of the record,
> > >>> method reference and intersection type doesn't mix well.
> > >>>
> > >>> public class RecordBadType {
> > >>>     interface  I {}
> > >>>     static abstract class C { }
> > >>>     static class A extends C implements I { }
> > >>>     static class B extends C implements I { }
> > >>>
> > >>>     static String f(I i) { return null; }
> > >>>
> > >>>     public static void main(String[] args) {
> > >>>       Stream.of(new A(), new B())
> > >>>         .map(RecordBadType::f)   // here the compiler should generate a bridge method no ?
> > >>>         .forEach(System.out::println);
> > >>>     }
> > >>> }
> > >>>
> > >>> this code compiles but you get a LambdaConversionException at runtime.
> > >>>
> > >>> Rémi
> >


More information about the compiler-dev mailing list