RFR 8144903: JShell: determine incorrectly the type of the expression which is array type of captured type

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Dec 9 12:39:40 UTC 2015


Hi Shinya,
In my experience, the best way to get to an usable declared type from a 
capture type is to always follow the wildcard - i.e. the upper bound of 
a captured type is more of an internal type system info (the result of 
capture conversion) and I don't think it should be used.

That said, I think there's a problem here: captured vars can appear in 
two places, type position or type-argument position:

1) Type position

class Foo<X> {
    X get() { .. }
}

Foo<? extends String> fs = ...
fs.get(); // you get a #CAP in a type position - i.e. the return type of 
get()

2) Type-argument position

class Foo2<X> {
    List<X> get() { .. }
}

Foo<? extends String> fs = ...
fs.get(); // you get a List<#CAP>, so #CAP is in a type-argument position

I think the TypePrinter should have some logic to detect as to whethe 
you are in case #1 or #2, and if in #1 it should drop wildcards to the 
floor; if it's in #2 it is ok to retain wildcards. So, I think a good 
solution would emit String for #1 and List<? extends String> for #2.

As usual - this is my 0.02$ :-)

[This is essentially an inference problem - we are trying to infer a 
denotable type from the type of an expression which might contain 
non-denotable types - the problem is not too different from what we have 
to do when the functional interfaces that are the target of a lambda 
conversion contains wildcards].

Maurizio

On 09/12/15 00:34, Robert Field wrote:
> Exactly, Shinya. Still curious of Jan's thinking.
>
> -Robert
>
>
>
> On December 8, 2015 15:13:42 ShinyaYoshida <bitterfoxc at gmail.com> wrote:
>
>> Hi Robert,
>> Thank you for your review and comments.
>>
>> 2015-12-09 5:28 GMT+09:00 Robert Field <robert.field at oracle.com>:
>>
>>> [Jan, I'd like your opinion]
>>>
>>> Thank you for seeing this and drilling into where the problem is.  
>>> This is
>>> important to fix.
>>>
>>> I see that this would address the problem.  However, I am squeamish 
>>> about
>>> the solution as it unwraps to match the result of layers of underlying
>>> super class behavior.  Looking at it further, I believe the problem 
>>> is in
>>> the pre-existing typeToPrint, my bad!  I don't think the approach I 
>>> took is
>>> right.  Stepping back, we want upper bound unless the type is 
>>> embedded in a
>>> type that takes generic types, class types.  That suggests to me 
>>> replacing
>>> typeToPrint with a boolean useWildCard = false, which would be 
>>> changed by
>>> visitClassType().  But alas this is recursive and this visitor does not
>>> have state that passes through the recursion, so it would be global 
>>> -- in
>>> this case that should work, but ugly.
>>>
>> Certainly, my fix is too depend on the super implementation.
>> The fix which you mentioned is like this, right?
>> http://cr.openjdk.java.net/~shinyafox/kulla/8144903/webrev.01_0/
>>
>>
>>
>>> Ah! Really the problem is that we want the top-level type to be erased.
>>> But that means holding an instance of Types.  Deeper integration with
>>> javac.  Hmmmm....
>>>
>> Another possible fix is making TypePrinter general(no recursive 
>> state) and
>> adding the print method what is erase top-level capture to TypePrinter,
>> using the print method at callsite:
>> http://cr.openjdk.java.net/~shinyafox/kulla/8144903/webrev.01_1/
>>
>> Regards,
>> shinyafox(Shinya Yoshida)
>>
>>
>>>
>>>
>>> -Robert
>>>
>>> On Dec 8, 2015, at 1:10 AM, ShinyaYoshida <bitterfoxc at gmail.com> wrote:
>>>
>>> Hi Robert,
>>> Could you review my patch for
>>> "JShell: determine incorrectly the type of the expression which is 
>>> array
>>> type of captured type"?
>>> https://bugs.openjdk.java.net/browse/JDK-8144903
>>>
>>> webrev: http://cr.openjdk.java.net/~shinyafox/kulla/8144903/webrev.00/
>>>
>>> Regards,
>>> shinyafox(Shinya Yoshida)
>>>
>>>
>>>



More information about the kulla-dev mailing list