| Summary: | [10] [compiler] eclipse rejects code that is compiled by javac involving wildcard and var declarations | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Sasikanth Bharadwaj <sasikanth.bharadwaj> |
| Component: | Core | Assignee: | Stephan Herrmann <stephan.herrmann> |
| Status: | CLOSED NOT_ECLIPSE | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | manoj.palat, stephan.herrmann |
| Version: | 4.8 | ||
| Target Milestone: | 4.16 M1 | ||
| Hardware: | PC | ||
| OS: | Windows 10 | ||
| Whiteboard: | stalebug | ||
(In reply to Sasikanth Bharadwaj from comment #0) > The following code is rejected by eclipse while it is accepted by javac > javac seems to be doing an additional capture I'd say it needs an additional erasure, not capture, to arrive at Object for the var's type, no? Do type projections cover this? If we consider the above snippet as the following:
public class X {
static void foo(Z<?> ef) {
Iterable<? super Y> iter = ef.t; // put into a local declaration
for (var v : iter) {
v = new Object(); // passes
}
for (Object l : ef.t) {
l = new Object();
}
}
}
class Y{ }
class Z<T extends Iterable<? super Y>> {
T t;
}
in this case, the enhanced-for is split with an initial local variable declaration iter - this will have Iterable<? super Y> as the type.
Inside the for-each, the collection type resolves to "Iterable<capture#2-of ? super Y>"
And hence the element type resolves to "capture#2-of ? super Y"
On this element, we do type projection and we get "Object" and it passes.
I believe we are missing the capture conversion of an implicit local variable in for-each.
my 2 cents and first attempt at type proj :)
Adding that, we have javac also compiling this code. [unrelated, but found an NPE while investigating this - bug 532920]
(In reply to comment #1) > (In reply to Sasikanth Bharadwaj from comment #0) > > The following code is rejected by eclipse while it is accepted by javac > > javac seems to be doing an additional capture > > I'd say it needs an additional erasure, not capture, to arrive at Object for the > var's type, no? Do type projections cover this? I don't think so, haven't seen erasures mentioned any where in projection. As elaborated in comment 1, the element type of the Collection seems to be the issue here. While we conclude that the type X for which collection type is a subtype of Iterable<X> is Iterable<? super Y>, javac concludes that it is Iterable<capture # of ? super Y>. Here's another similar case where both compilers report error. import java.util.Iterator; public class X { static void foo(Z<?> ef) { for (var l : ef.t) { l = new Object(); } } } class I<T> implements Iterable<T> { @Override public Iterator<T> iterator() { // TODO Auto-generated method stub return null; } } class Q{} class Y extends Q{ } class Z<T extends Iterable<? super Y>> { I<T> t; } Here, X is again the wildcard ? super Y. Need to figure out what's the difference between these two cases This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie. (In reply to Sasikanth Bharadwaj from comment #3) > (In reply to comment #1) > > (In reply to Sasikanth Bharadwaj from comment #0) > > > The following code is rejected by eclipse while it is accepted by javac > > > javac seems to be doing an additional capture > > > > I'd say it needs an additional erasure, not capture, to arrive at Object for the > > var's type, no? Do type projections cover this? > I don't think so, haven't seen erasures mentioned any where in projection. > As elaborated in comment 1, the element type of the Collection seems to be > the issue here. While we conclude that the type X for which collection type > is a subtype of Iterable<X> is Iterable<? super Y>, javac concludes that it > is Iterable<capture # of ? super Y>. A quick look at a recent version of JLS 14.14.2 I see no indication of any capture nor erasure happening. If javac invents any captures that seems to be their bug. |
The following code is rejected by eclipse while it is accepted by javac javac seems to be doing an additional capture - I could not find the relevant section in JLS that requires this. Need to investigate public class X { static void foo(EFVar<?> ef) { for (var v : ef.t) { v = new Object(); // error here - Type mismatch } for (Object l : ef.t) { l = new Object(); } } } class Y { } class EFVar<T extends Iterable<? super Y>> { T t; }