Intersection type and method ref bug ?
Vicente Romero
vicente.romero at oracle.com
Thu Oct 22 15:32:32 UTC 2020
Hi Bernard,
The PR is not final yet, I want to do some research. The change you are
referring to has nothing to do with your patch but I think it is the
right thing to do. I will investigate why those tests are failing.
Vicente
On 10/22/20 8:18 AM, B. Blaser wrote:
> 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