Incoherent invocation type inference?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Jan 16 15:25:11 UTC 2017



On 16/01/17 12:51, Maurizio Cimadamore wrote:
> I don't think intersection types are the evil in your example. Even 
> leaving intersection types aside:
>
> class Issue  {
>     <T> T get() { return (T)new ArrayList<String>(); }
>
>     void run() {
>         LinkedList<String> ll = null;
>         ll = get(); // OK, but will fail at runtime due to unchecked 
> conversion in get().
>     }
>
>     public static void main(String... args) {
>         new Issue().run();
>     }
> }
>
> So, I guess I'm not exactly sure of what we're trying to improve here? 
To clarify - what I'm saying here is: the main issue is that get() is 
promising that ArrayList<String> will be compatible with T. This promise 
is unsound - as T is basically controlled by client code, so it can be 
fixed to whatever type the client wants. That's the condition that 
smells, IMHO.

It's true that, as Remi pointed out, there are cases where unchecked 
conversion and return type inference play well together - as in 
Collections.emptyList - but there's a big difference in that method:

public static final <T> List<T> emptyList()

The return type here is not a naked type-variable T - but List<T>. So, 
while the client can control the parameterization (List<String> vs 
List<Integer>) it *cannot* control the base type (List vs String).

The combination of unchecked return assignment and a naked generic 
method type-variable return are IMHO always a source of smell in generic 
code - that's what I was referring to with the Lint digression.

As far as intersection types are concerned - I sense that it's easier to 
add new well-formedness rules about such types rather than changing the 
way in which inference constraints are set up based on finality of a 
class. Having such checks would also prevent users from spelling bad 
intersection types in their code (e.g. a cast with an intersection type 
target - which is possible since Java SE 8).

Maurizio


More information about the compiler-dev mailing list