Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 427694

Summary: [1.8][compiler] Functional interface not identified correctly
Product: [Eclipse Project] JDT Reporter: Noopur Gupta <noopur_gupta>
Component: CoreAssignee: Stephan Herrmann <stephan.herrmann>
Status: VERIFIED WONTFIX QA Contact:
Severity: normal    
Priority: P3 CC: daniel_megert, jarthana, manoj.palat, markus.kell.r, srikanth_sankaran, stephan.herrmann
Version: 4.4   
Target Milestone: 4.14 M3   
Hardware: All   
OS: All   
See Also: https://bugs.eclipse.org/bugs/show_bug.cgi?id=400386
Whiteboard:

Description Noopur Gupta CLA 2014-02-07 12:48:42 EST
package test.fi;

interface I { Object m(Class c); }
interface J<S> { S m(Class<?> c); }
interface K<T> { T m(Class<?> c); }
interface Functional<S,T> extends I, J<S>, K<T> {}
---------------------------------------------------------------

The above example shows error "The return types are incompatible for the inherited methods K<T>.m(Class<?>), J<S>.m(Class<?>), K<T>.m(Class<?>)" at "Functional" with ECJ, but compiles with b128.
Comment 1 Srikanth Sankaran CLA 2014-02-14 00:53:51 EST
This was the same issue that was raised to the spec committee and reported
here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=400386

This code does not compile under JDK5,6,7 and ECJ 1.5,1.6,1.7,1.8

I am sorry, I don't understand what "however: when functional interfaces are implicitly implemented, the overriding effectively occurs generically; " means.
(this passage which I am not able to make sense of has been removed from the
latest draft)

The latest spec says: 

... but Functional<String,Integer> clearly cannot be implemented with a single 
method. However, other parameterizations of Functional can be implemented with 
a single method.

The only parameterization I am able to write using these interfaces without
triggering an error from javac is:

Functional<Object, Object> f = (p) -> null; 

If some one gives me a useful example, I am willing to pull this up for GA,
otherwise it is going to stay untargetted as an extreme corner case.
Comment 2 Timo Kinnunen CLA 2014-02-14 20:22:03 EST
Well, this one at least works:

    Functional<Number, Integer> func1 = new Functional<Number, Integer>() {
      @Override
      public Integer m(Class c) {
        return c.getModifiers();
      }
    };
    
And yet this doesn't:

    Functional<Number, Integer> func2 = (Class c) -> c.getModifiers();
    
Nor this:

    Functional<Number, Integer> func3 = Class::getModifiers;
Comment 3 Srikanth Sankaran CLA 2014-09-01 04:13:12 EDT
Don't expect to be able to get to this anytime soon.
Comment 4 Eclipse Genie CLA 2019-10-24 15:40:00 EDT
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.

If you have further information on the current state of the bug, please add it. 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.
Comment 5 Stephan Herrmann CLA 2019-10-26 18:09:45 EDT
(In reply to Noopur Gupta from comment #0)
> package test.fi;
> 
> interface I { Object m(Class c); }
> interface J<S> { S m(Class<?> c); }
> interface K<T> { T m(Class<?> c); }
> interface Functional<S,T> extends I, J<S>, K<T> {}
> ---------------------------------------------------------------
> 
> The above example shows error "The return types are incompatible for the
> inherited methods K<T>.m(Class<?>), J<S>.m(Class<?>), K<T>.m(Class<?>)" at
> "Functional" with ECJ, but compiles with b128.

interface I uses a raw type Class. If I change that to Class<?> also javac (versions 8 - 13) reports an error:
Functional.java:5: error: types K<T> and J<S> are incompatible; both define m(java.lang.Class<?>), but with unrelated return types
interface Functional<S,T> extends I, J<S>, K<T> {}
^
  where T,S are type-variables:
    T extends Object declared in interface Functional
    S extends Object declared in interface Functional
1 error


=> I assume this is just a glitch in raw type handling, s.t. like javac believing that I.m() overrides both J.m and K.m, but only if the argument is not the same, huh?? Is method verification switching to erasures when one method with raw types is involved?? No idea where this would be found in the spec.
Comment 6 Jay Arthanareeswaran CLA 2019-11-20 05:17:22 EST
Verified for 4.14 M3