RFR: 8295020: javac emits incorrect code for for-each on an intersection type.

Srikanth Adayapalam sadayapalam at openjdk.org
Fri Oct 14 10:24:00 UTC 2022


On Fri, 14 Oct 2022 10:10:10 GMT, Maurizio Cimadamore <mcimadamore at openjdk.org> wrote:

>> Eliminate needless casts and ensure invoked method is looked up against the appropriate receiver type
>
> src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java line 3526:
> 
>> 3524:             Symbol iterator = lookupMethod(tree.expr.pos(),
>> 3525:                                            names.iterator,
>> 3526:                                            tree.expr.type,
> 
> The real problem here is that the target type of the cast (which ends up in tree.expr.type) and the type used for the lookup in the old code (eType) diverge. The latter might still have references to the source type - e.g. in this case to the covariant MyIterable, so looking up a method there will result in an iterator of some unexpected type. This is not wrong per se, but it should be fixed one way or another (e.g. by always using Iterable, as you have done), or by correctly honoring the covariant type.
> 
> A really unfortunate combination of issues here - there is a latent discrepancy of types (eType != tree.expr.type), but that only results in bugs when a cast to Iterable is added (which only happens for interaction types).

Actually it is not the case that we always lookup iterator() from Iterable. The test case shows two scenarios, one where
iterator() comes from expr's erased type (MyIterable) and is called using invokevirtual & returns a covariant type (MyIterable.MyIterator) and another where iterator() comes from Iterable (expr's erased type casted),
and will be called by invokeinterface and return Iterator.

Right, what the patch is trying hard to avoid is the divergence.

-------------

PR: https://git.openjdk.org/jdk/pull/10710


More information about the compiler-dev mailing list