| Summary: | [1.8][compiler] Compiler fails to compile AnnotatedElement | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Srikanth Sankaran <srikanth_sankaran> |
| Component: | Core | Assignee: | Stephan Herrmann <stephan.herrmann> |
| Status: | VERIFIED FIXED | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | jarthana, noopur_gupta |
| Version: | 4.4 | ||
| Target Milestone: | BETA J8 | ||
| Hardware: | PC | ||
| OS: | Windows 7 | ||
| Whiteboard: | |||
| Bug Depends on: | |||
| Bug Blocks: | 427787 | ||
|
Description
Srikanth Sankaran
Thanks for taking a look, I'll tackle https://bugs.eclipse.org/bugs/show_bug.cgi?id=428261 and once these are taken care of, Jay can devise some ways to package and test. First thing tomorrow :) Minimal repro:
//----
import java.util.*;
import java.util.function.Function;
import java.util.stream.*;
interface Bar {
Class<? extends Bar> type();
}
public class X {
<T extends Bar> T[] test(Class<T> barClass, Stream<Bar> bars) {
return get(bars.
collect(Collectors.toMap(Bar::type,
Function.identity(),
((first,second) -> first),
HashMap::new)),
barClass);
}
<A extends Bar> A[] get(Map<Class<? extends Bar>,Bar> m, Class<A> c) {
return null;
}
}
//----
This is an interesting case: trouble occurred at this constraint:
⟨bars.collect(Collectors.toMap(..)) → java.util.Map<java.lang.Class<? extends Bar>,Bar>⟩
Here the spec (18.2.1) clearly says:
"A constraint formula of the form ⟨Expression → T⟩ is reduced as follows:
If T is a proper type, the constraint reduces to true if the expression is compatible in a loose invocation context with T (5), and false otherwise."
Problem was: after applicability inference the inner ("toMap") has type
Map<Class<capture#3-of ? extends Bar>,Bar>
which is *not* compatible with its non-captured variant. Bummer!
First guess: maybe compatibility should be checked after finishing inner inference. This indeed fixes the immediate issue, but then we ended up comparing an unsubstituted type variable (U, declared by toMap) with its inference solution Bar and again incompatibility was detected.
The solution is to include inner inference into the current inference. Interestingly, a few bullets down in 18.2.1 we have "the constraint reduces to the bound set B3 ...", which exactly solves the problem.
Even more interestingly, the initial "If T is a proper type" is separated from the other bullet by a chain of "Otherwise, if .., Otherwise". I conclude that javac is interpreting this "Otherwise" in a non-exclusive way. Which is extremely interesting, as also the case reported in [1] can be explained using a non-exclusive interpretation of "Otherwise".
Test & fix released via http://git.eclipse.org/c/jdt/eclipse.jdt.core.git/commit/?h=BETA_JAVA8&id=b0e8687830f97b9ddeb50b010730e5d2fdfd5916
[1] http://mail.openjdk.java.net/pipermail/lambda-spec-experts/2014-February/000507.html
Verified as working for Eclipse + Java 8 RC1 using Kepler SR2(RC4) + Eclipse Java Development Tools Patch for Java 8 Support (BETA) 1.0.0.v20140220-2054 |