Bug 531094 - [1.8][inference] Type error on functional interface assignment in generics method
Summary: [1.8][inference] Type error on functional interface assignment in generics me...
Status: NEW
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 4.7.2   Edit
Hardware: PC Linux
: P3 major (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords: helpwanted
Depends on:
Blocks:
 
Reported: 2018-02-13 06:40 EST by Bug Menot CLA
Modified: 2022-06-01 18:03 EDT (History)
2 users (show)

See Also:


Attachments
Test case class (711 bytes, text/x-java)
2018-02-13 06:40 EST, Bug Menot CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Bug Menot CLA 2018-02-13 06:40:03 EST
Created attachment 272660 [details]
Test case class

See the attachment; the attached class (inserted in a plain Java project) won't compile in Eclipse; however it compiles and run without errors on both Netbeans and IntelliJ.

Compilation error is:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
	Type mismatch: cannot convert from List<AbstractMap.SimpleEntry<Object,String>> to List<Map.Entry<OneLinerMapInitializer.MapStrategy,String>>
	The target type of this expression must be a functional interface
	The target type of this expression must be a functional interface
	The target type of this expression must be a functional interface

	at OneLinerMapInitializer.main(OneLinerMapInitializer.java:22)
Comment 1 Stephan Herrmann CLA 2018-02-13 09:12:54 EST
Thanks, I can see that ecj rejects and javac accepts this.

From a quick glance it's hard to tell which is the correct behavior.

Seeing a functional interfaces with wildcards, javac's bug re wildcard widening [1] could have a finger in the pie, but more importantly:

The use of raw types puts this example into an area, where javac, JLS and ecj are known to deviate in ways which may be impossible to resolve without changes in JLS.

For further analysis I added missing type information to yield a program that ecj accepts:
//---
import java.util.*;
public class OneLinerMapInitializer {
    @FunctionalInterface
    public interface MapStrategy {Map<?,?> getMap();}
    public static Map<?,String> getMap1() {
        return null;
    }
    public static Map<?,String> getMap2() {
        return null;
    }
    public static Map<?,String> getMap3() {
        return null;
    }
    public static void main(String[] args) {
        final List<Map.Entry<MapStrategy,String>> lll = Arrays.asList(
                new AbstractMap.SimpleEntry<MapStrategy,String>(OneLinerMapInitializer::getMap1,""),
                new AbstractMap.SimpleEntry<MapStrategy,String>(OneLinerMapInitializer::getMap2,""),
                new AbstractMap.SimpleEntry<MapStrategy,String>(OneLinerMapInitializer::getMap3,"")
        );
    }
}
//---

Obviously, this version can be used by clients as a workaround.

What's fishy now: omitting the explicit type arguments of the SimpleEntry contructor invocations (to use diamonds) makes ecj fail again.

The same difference can be exhibited even without wildcards:
//---
import java.util.*;
public class OneLinerMapInitializer {
    @FunctionalInterface
    public interface MapStrategy {Map<Object,String> getMap();}
    public static Map<Object,String> getMap1() {
        return null;
    }
    public static Map<Object,String> getMap2() {
        return null;
    }
    public static Map<Object,String> getMap3() {
        return null;
    }
    public static void main(String[] args) {
        final List<Map.Entry<MapStrategy,String>> lll = Arrays.asList(
                new AbstractMap.SimpleEntry<MapStrategy,String>(OneLinerMapInitializer::getMap1,""),
                new AbstractMap.SimpleEntry<MapStrategy,String>(OneLinerMapInitializer::getMap2,""),
                new AbstractMap.SimpleEntry<MapStrategy,String>(OneLinerMapInitializer::getMap3,"")
        );
    }
}
//---

Same as above: accepted by ecj but rejected when changed to use diamonds. With no influence of wildcards nor raw types this sure looks like a bug in ecj.

[1] https://bugs.openjdk.java.net/browse/JDK-8016207
Comment 2 Manoj N Palat CLA 2018-05-17 03:23:00 EDT
bulk move out of 4.8
Comment 3 Manoj N Palat CLA 2018-08-16 00:09:08 EDT
Bulk move out of 4.9
Comment 4 Eclipse Genie CLA 2022-06-01 18:03:05 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.