| Summary: | Wildcard 'Type mismatch' | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Chris Hubick <chris> |
| Component: | Core | Assignee: | Stephan Herrmann <stephan.herrmann> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | jarthana, stephan.herrmann |
| Version: | 4.5 | ||
| Target Milestone: | 4.15 M3 | ||
| Hardware: | PC | ||
| OS: | Linux | ||
| Whiteboard: | stalebug | ||
Reproducible on master, looks likes a regression after bug 437444 was fixed. Sasi, please take it forward. This can be traced to this change in CEF.reduceReferenceExpressionCompatibility - TypeBinding rPrime = compileTimeDecl.isConstructor() ? compileTimeDecl.declaringClass : compileTimeDecl.returnType; + TypeBinding rPrime = compileTimeDecl.isConstructor() ? compileTimeDecl.declaringClass : compileTimeDecl.returnType.capture(inferenceContext.scope, reference.sourceEnd()); Removing the capture solves the issue. And it does not impact any java8 tests.Trying to find an explanation for why this was required and why it isn't needed any more (In reply to Sasikanth Bharadwaj from comment #2) > This can be traced to this change in > CEF.reduceReferenceExpressionCompatibility > - TypeBinding rPrime = compileTimeDecl.isConstructor() ? > compileTimeDecl.declaringClass : compileTimeDecl.returnType; > + TypeBinding rPrime = compileTimeDecl.isConstructor() ? > compileTimeDecl.declaringClass : > compileTimeDecl.returnType.capture(inferenceContext.scope, > reference.sourceEnd()); > > Removing the capture solves the issue. And it does not impact any java8 > tests.Trying to find an explanation for why this was required and why it > isn't needed any more From a SPEC we should *always* apply capture here (i.e., also to compileTypeDecl.declaringClass). We're looking at the last bullet in 18.2.1: "let R' be the result of applying capture conversion (§5.1.10) to the return type of the invocation type (§15.12.2.6) of the compile-time declaration" Not doing so before bug 437444 was on oversight on my behalf. Unless this is being changed by one of the JDK bugs referenced in bug 437444, we should not lightly remove capturing. (In reply to comment #3) > > From a SPEC we should *always* apply capture here (i.e., also to > compileTypeDecl.declaringClass). We're looking at the last bullet in 18.2.1: > "let R' be the result of applying capture conversion (§5.1.10) to the return > type of the invocation type (§15.12.2.6) of the compile-time declaration" > > Not doing so before bug 437444 was on oversight on my behalf. > > Unless this is being changed by one of the JDK bugs referenced in bug 437444, we > should not lightly remove capturing. Thanks Stephan for the pointer. This leads me to believe that we are doing the right thing here. Replacing the method reference Optional::get with the lambda (o) -> {return o.get();} causes javac to complain as well. Breaking up the statement into two like Stream<TextNode<?>> s = docs.stream().map((root) -> root.getChild(id)).filter(Optional::isPresent).map(Optional::get); return s.findAny(); is accepted but in a single statement, the capture would be present in the type of the invocation and hence the return type will be incompatible with the declared type I'm still looking in the spec to find something that would dictate the behavior to be different. Stephan, another push in the right direction please... Providing an explicit type to Stream.map() also seems to be accepted:
> return docs.stream().map((root) -> root.getChild(id)).filter(Optional::isPresent).<TextNode<?>> map(Optional::get).findAny();
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. The most closely related spec bug is https://bugs.openjdk.java.net/browse/JDK-8054721 which has not produced a solution in over 5 years. Ergo we will do the same: nothing. |
> import java.util.*; > import java.util.function.*; > import java.util.stream.*; > > public class Test { > > public abstract static class TreeNode<ChildT extends TreeNode<?>> { > public abstract Optional<ChildT> getChild(String id); > } > > public abstract static class TextNode<ChildT extends TextNode<?>> extends TreeNode<ChildT> {} > > public abstract static class Document extends TreeNode<TextNode<?>> {} > > public static final Optional<TextNode<?>> getChildByID(List<Document> docs, String id) { > return docs.stream().map((root) -> root.getChild(id)).filter(Optional::isPresent).map(Optional::get).findAny(); // ERROR: Type mismatch: cannot convert from Optional<Test.TextNode<capture#1-of ?>> to Optional<Test.TextNode<?>> > } > > } eclipse.buildId=4.5.0.I20141216-0800 java.version=1.8.0_25 Compiles fine with javac.