Incoherent invocation type inference?

B. Blaser bsrbnd at
Mon Jan 16 16:49:50 UTC 2017

2017-01-16 16:25 GMT+01:00 Maurizio Cimadamore <maurizio.cimadamore at>:
> 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

Intersections seem to be dangerous only in the case of a naked return
type variable with no parameter provided ("get()" or "get(null)")
because get() wouldn't know about the return type constraints. We
could, for example, update the rule as follows: "emit a lint warning
if the return type T is a naked type variable infered to an
intersection type and no constraint is given by the actual arguments"?

Or are you suggesting to modify the rules of intersection types on the
language side?


More information about the compiler-dev mailing list