Incoherent invocation type inference?
Remi Forax
forax at univ-mlv.fr
Fri Jan 13 14:50:11 UTC 2017
----- Mail original -----
> De: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> À: "B. Blaser" <bsrbnd at gmail.com>, compiler-dev at openjdk.java.net
> Envoyé: Vendredi 13 Janvier 2017 15:12:35
> Objet: Re: Incoherent invocation type inference?
> I think that's correct behavior. When you say something like:
>
> li = get(null);
>
>
> T will get two constraints:
>
> * an upper bound (from declared bound) : T <: Iterable<String>
> * an upper bound (from return type compatibility) : T <: Integer
>
> The language will then infer T = Integer & Iterable<String>, an
> intersection type.
>
> Normally this would be fine - but the issue here is that Integer is a
> final class, so that intersection type has no witnesses - e.g. there's
> no way for get() to construct a type that is both an Integer and an
> Iterable<String> - so that will almost always fail - unless get()
> returns null.
>
> That said, I'm not aware of any check in the spec for preventing an
> intersection type to mention a final class as one of its components so,
> while this does look weird, I think the compiler is doing what the
> language spec says.
The spec can not use the fact that a class is final because it's a source and binary compatible change to remove final for a class.
You will break the encapsulation if the class is used by another class but that's another story.
>
> Maurizio
>
Rémi
>
> On 13/01/17 13:01, B. Blaser wrote:
>> mport java.util.*;
>>
>> public class Issue {
>> <T extends Iterable<String>> T get() { return (T)new ArrayList<String>(); }
>> <T extends Iterable<String>> T get(T t) { return (T)new
>> ArrayList<String>(); }
>>
>> void run() {
>> List<String> li = null;
>> LinkedList<String> ll = null;
>> Integer i = null;
>>
>> li = get(null);
>> i = get(null); // Shouldn't compile? and will fail at runtime.
>> // i = get(li); // Fails as expected
>>
>> li = get();
>> ll = get(); // OK, but will fail at runtime due to unchecked
>> conversion in get().
>> i = get(); // Shouldn't compile? and will fail at runtime.
>> }
>>
>> public static void main(String... args) {
>> new Issue().run();
>> }
> > }
More information about the compiler-dev
mailing list