JDK-8153748 : Inference: stuck expressions should not be considered ahead of target-type constraints evaluation
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8-pool,9
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2016-04-07
  • Updated: 2017-12-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_majorUnresolved
Related Reports
Blocks :  
Description
The following program should fail to compile but it doesn't:

import java.util.*;
import java.util.function.*;

class ObjectTargetType {

<T, R> R m(List<? extends R> l1, List<? extends R> l2, Function<String, R> fun) {
    return fun.apply(null);
}

void test(List<Class<RuntimeException>> l1, List<Class<Exception>> l2) {
    Object o = m(l1, l2, s -> String.class); // error???
}

}


Comments
Need to think about this case, too -- currently javac rejects, because resolving R for the target type constraint takes priority over resolving T for the lambda constraint: <T, R> R m(List<? extends R> l1, List<? extends R> l2, Function<T, R> fun) { return fun.apply(null); } void test(List<Class<RuntimeException>> l1, List<Class<Exception>> l2) { Object o = m(l1, l2, s -> String.class); // error m(l1, l2, s -> String.class); // ok }
10-06-2016

This is a difference between JLS and javac when implementing invocation type inference. The JLS builds invocation inference on applicability inference and then adds additional constraints; when doing so, target type analysis takes precedence, so eager instantiation (from target type evaluation) could precede evaluation of stuck expressions. Javac behavior is slightly different - instead of simply repeating the applicability inference step, javac redoes that step in a slightly different way - so that expressions that were considered not pertinent to applicability in the earlier round can now be considered so (because the target type is ground). As a result, javac will evaluate the lambda expression *before* reasoning about the target type. That's why the program above passes compilation.
07-04-2016