Community
Participate
Working Groups
0.6.1 9.8 is silent about descriptor computation in the presence of raw types. Is this specified somewhere else ? Discouraged though this scenario may be, we can expect to run into this sooner or later, intentionally coded or otherwise. The reference compiler at 8b74 seems to erase the descriptor as seen by the following program: This seems reasonable from one pov. From another, this is somewhat at odds with the ban on lambdas implementing generic methods in that, in both cases we have (or are likely to have) unadaptable type variable usage in various constituents of the descriptor. And the target type is raw in one case and the lambda is "raw" in the other case (by virtue of there being no grammar support for type parameter encoding) I am happy erasing the descriptor, but (a) should this stay unspecified if it indeed is and (b) does the inconsistency in treatment with generic lambdas OK ? // --- import java.util.List; interface I<T> { void foo(List<T> f); } class Y { void goo(I<String> f) { } } class Z { void zoo(I f) { } } public class X { public static void main(String [] args) { new Y().goo((List<String> ls) -> {}); // Compiles OK with 8b74 new Z().zoo((List ls) -> {}); // OK } } -------------------- To see the correlation between generic lambdas and raw types in target type study this program in which 8b74 is inadvertently allowing a generic lambda since it does not see the descriptor as being generic due to erasure: // ----- import java.util.List; interface I<T> { <P> P foo(List<T> f); } class Y { void goo(I<String> f) { } } class Z { void zoo(I f) { } } public class X { public static void main(String [] args) { new Y().goo((List<String> ls) -> { return null; }); // Fails: descriptor is generic new Z().zoo((List ls) -> { return null; }); // compiles fine, we are overriding a generic method with another that has no type variables!! } }
org.eclipse.jdt.core.tests.compiler.regression.NegativeLambdaExpressionsTest.test400556k() encodes the current eclipse behavior which is compatible with javac 8b74.
This has been acknowledged as a gap in the spec and is being addressed to require that descriptor be erased - a behavior javac and ECJ already implement. With erasure required, the descriptor is not generic any more and so the issue of the lambda implementing a generic descriptor goes away automatically.