Community
Participate
Working Groups
Continued from bug 465859: This program is rejected by ecj and javac alike: //--- import java.util.*; import java.util.stream.*; import static java.util.Arrays.asList; public class C { static final List<Integer> DIGITS = Collections.unmodifiableList(asList(0,1,2,3,4,5,6,7,8,9)); Collection<String> flatMapSolutions(final boolean b) { Collection<String> solutions = DIGITS.stream().flatMap( s -> { return Stream.empty(); }) .collect(Collectors.toList()); return solutions; } } //--- But this variant is strangely accepted by javac: //--- import java.util.*; import java.util.stream.*; import static java.util.Arrays.asList; public class C { static final List<Integer> DIGITS = Collections.unmodifiableList(asList(0,1,2,3,4,5,6,7,8,9)); Collection<String> flatMapSolutions(final boolean b) { Collection<String> solutions = DIGITS.stream().flatMap( s -> { return b ? Stream.empty() : Stream.of(""); }) .collect(Collectors.toList()); return solutions; } } //--- Given how the ternary's type is determined from the target type, I don't see how the type hint from Stream.of("") could influence inference, but this is just looking from outside. Need detailed analysis.
If "accept" is indeed the correct answer then this is actually a regression introduced in 4.5 M3. Tentatively putting into the 4.5 box, not sure it will meet the deadline ...
Bug 463728 _could_ be related
The ternary is resolved twice: First, during inference of the enclosing flatMap() invocation, against a target type of: Stream<? extends R#0>. This attempt resolves "Stream.empty()" to Stream<Object>. Second, on behalf of ASTNode.resolvePolyExpressionArguments() when inference is mostly done and R#0 has already been instantiated to j.l.Object (expected type for the ternary is now Stream<? extends Object>). This is definitely too late for finding j.l.String as a solution. During the first attempt, I see a dependency T#1 <: R#0 with T#1 standing for the type parameter of Stream.of() R#0 standing for the type parameter of flatMap() but a non-proper upper bound of T#1 is ignored during resolve. Hence T#1 is instantiated to j.l.Object which then percolates in all other parts of the inference. Ergo: I couldn't find an obvious oversight regarding ternary expressions. Additionally, I could pin-point bug 437444 as causing us to reject the program. The size and nature of that fix also means, it won't be easy to identify what causes the change in behavior. We could even argue that this is not a regression proper, because strictly speaking after bug 437444 ecj compiles a different language than before (see, e.g., bug 437444 comment 162). => Moving to 4.6 for continued investigation.
Fixed on by commit 31d25259b58c3c4c3c062013eb31d95cf4a9f389 behalf of Bug 463728 Test released via commit fbf034987e479beebb50addc92136d221961bff3 *** This bug has been marked as a duplicate of bug 463728 ***
Verified for Eclipse Mars 4.5 SR1 (4.5.1) Build id: M20150819-1000