Intersection type and method ref bug ?
Vicente Romero
vicente.romero at oracle.com
Tue Oct 20 20:06:15 UTC 2020
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