| Summary: | "Bound mismatch" error with ternary operator | ||
|---|---|---|---|
| Product: | [Eclipse Project] JDT | Reporter: | Greg Brown <gk_brown> |
| Component: | Core | Assignee: | Srikanth Sankaran <srikanth_sankaran> |
| Status: | VERIFIED DUPLICATE | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | CC: | amj87.iitr, deepakazad, srikanth_sankaran |
| Version: | 3.7 | ||
| Target Milestone: | 3.7.1 | ||
| Hardware: | Macintosh | ||
| OS: | Mac OS X - Carbon (unsup.) | ||
| Whiteboard: | |||
I'll take a look. (In reply to comment #0) > Build Identifier: M20110210-1200 > > When using a ternary operator to invoke a parameterized method with a > recursively-defined parameter type, a "bound mismatch" compiler error is > incorrectly reported. This error does not occur when compiling with javac Hello Greg, which version of javac did you test with ? I get an error with both javac5 and javac6 while JDK7 goes into tail spin and crashes out. > Hello Greg, which version of javac did you test with ? I get an error with
> both javac5 and javac6 while JDK7 goes into tail spin and crashes out.
I got this error with Java 6. I haven't tried to reproduce it in Java 7.
(In reply to comment #3) > > Hello Greg, which version of javac did you test with ? I get an error with > > both javac5 and javac6 while JDK7 goes into tail spin and crashes out. > > I got this error with Java 6. I haven't tried to reproduce it in Java 7. Your earlier assertion (comment#0) was that javac compiled it fine. May be that was a different version than the one you are trying now ? Do you have finer grained version number than Java 6 ? From my end, I am trying to get the latest builds for JDK5,6,7 and test this out - having some issues with our archival server at the moment. > Your earlier assertion (comment#0) was that javac compiled it fine. May be
> that was a different version than the one you are trying now ?
I believe it was J6u22 (Mac OS X). And yes, javac did compile fine - I only saw this error within Eclipse.
(In reply to comment #5) > > Your earlier assertion (comment#0) was that javac compiled it fine. May be > > that was a different version than the one you are trying now ? > > I believe it was J6u22 (Mac OS X). And yes, javac did compile fine - I only saw > this error within Eclipse. The latest versions of JDK5,6,7 all fail to compile the program. I didn't check with J6u22 itself, but it would appear that version may have regressed and was subsequently fixed. Here is JDK 1.5.22 and 1.6.27 matching eclipse behavior. C:\jtests>C:\jdk-1_5_0_22-fcs-bin-b03-windows-i586-09_oct_2009\jdk1.5.0_22\bin\j avac.exe -Xlint:unchecked -Xlint:deprecation -Xlint:rawtypes -sourcepath c:\jtes ts X.java X.java:19: incompatible types; inferred type argument(s) java.lang.Object do not conform to bounds of type variable(s) T found : <T>T required: java.lang.Object return flag ? null : (T)getC(); ^ 1 error C:\jtests>javac6 X C:\jtests>C:\jdk-6u27-fcs-bin-b07-windows-i586-19_jul_2011\jdk6_27\bin\javac.exe -Xlint:deprecation -Xlint:unchecked -sourcepath c:\jtests X.java X.java:19: incompatible types; inferred type argument(s) java.lang.Object do not conform to bounds of type variable(s) T found : <T>T required: java.lang.Object return flag ? null : (T)getC(); ^ 1 error I can confirm that this does not compile with javac 1.6.0_26 on Mac OS X. Thanks for looking into it. Much water has flown under the bridge since this bug was raised and here is a reconstruction: The behavior described in comment#0 where there is a blatant difference in treatment between an if-else statement and the ternary operator was a bug in eclipse. This bug does not show up anymore on 3.8 M3 nor 3.7.1. The underlying problem is the same reported in bug 242159 and bug 283353 where basically there is a mistreatment by eclipse of recursive formal bounds of type variables resulting in bounds mismatch. The fix for the above bugs was itself subsumed by the fix for bug 347600 which was an umbrella fix for several bugs as listed in bug 347600 comment# 9. An excerpt from the comment in org.eclipse.jdt.internal.compiler.lookup.ParameterizedGenericMethodBinding.computeCompatibleMethod(MethodBinding, TypeBinding[], Scope, InvocationSite) added as a part of the fix referred to above reads: /* bounds check: https://bugs.eclipse.org/bugs/show_bug.cgi?id=242159, Inferred types may contain self reference in formal bounds. If "T extends I<T>" is a original type variable and T was inferred to be I<T> due possibly to under constraints and resultant glb application per 15.12.2.8, using this.typeArguments to drive the bounds check against itself is doomed to fail. For, the variable T would after substitution be I<I<T>> and would fail bounds check against I<T>. Use the inferred types from the context directly - see that there is one round of extra substitution that has taken place to properly substitute a remaining unresolved variable which also appears in a formal bound (So we really have a bounds mismatch between I<I<T>> and I<I<I<T>>>, in the absence of a fix.) */ I believe the current behavior shown by eclipse is the correct one. You may want to report the 7b147 crash to Oracle - Thanks. *** This bug has been marked as a duplicate of bug 242159 *** Verified for 3.8M4 using build I20111202-0800. Just to clarify for future reference, the reporter saw a bug in an older eclipse release which has been fixed. javac 4,5 and 6 are themselves buggy and old behaviour matched those, but the bug was rectified in javac7 and has also been fixed in eclipse. (Note however that javac7b147 crashes with this test case.) Bottomline: the test should compile just like its if-else variant does. |
Build Identifier: M20110210-1200 When using a ternary operator to invoke a parameterized method with a recursively-defined parameter type, a "bound mismatch" compiler error is incorrectly reported. This error does not occur when compiling with javac or when an if/else block is used in place of the ternary operator. Example error message (produced when attempting to compile the attached sample program): Bound mismatch: The generic method getC() of type Test is not applicable for the arguments (). The inferred type List<List<T>> is not a valid substitute for the bounded parameter <T extends List<T>> Reproducible: Always Steps to Reproduce: package test; import java.util.List; public class Test { private boolean flag = true; public <T extends List<T>> T getA() { T a; if (flag) { a = null; } else { a = getC(); } return a; } @SuppressWarnings("unchecked") public <T extends List<T>> T getB() { return flag ? null : (T)getC(); } public <T extends List<T>> T getC() { return null; } }