Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 400881 - [1.8][spec] Clarification required on how raw types interact with interface descriptor computation.
Summary: [1.8][spec] Clarification required on how raw types interact with interface d...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.3   Edit
Hardware: PC Windows 7
: P3 normal (vote)
Target Milestone: BETA J8   Edit
Assignee: Srikanth Sankaran CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 401003
  Show dependency tree
 
Reported: 2013-02-15 01:50 EST by Srikanth Sankaran CLA
Modified: 2013-02-16 23:11 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Srikanth Sankaran CLA 2013-02-15 01:50:09 EST
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!!
    }
}
Comment 1 Srikanth Sankaran CLA 2013-02-15 01:51:55 EST
org.eclipse.jdt.core.tests.compiler.regression.NegativeLambdaExpressionsTest.test400556k() encodes the current eclipse behavior which is compatible with
javac 8b74.
Comment 2 Srikanth Sankaran CLA 2013-02-15 12:38:40 EST
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.