JDK-6541819 : Inference does not work in enhanced for loop
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 6,7
  • Priority: P5
  • Status: Open
  • Resolution: Unresolved
  • OS: generic,linux
  • CPU: generic,x86
  • Submitted: 2007-04-02
  • Updated: 2015-04-18
Related Reports
Duplicate :  
Relates :  
Description
I'm wondering if the below code is buggy:

import java.util.*;

public class Test {
    static <K,V> Iterable<Map.Entry<K,V>> getEntries() {return null;}    

    public static void main(String[] args) {
        for (Map.Entry<?,Integer> e : getEntries()) {
        }
    }
}


The compiler reports the following error:

Test.java:7: incompatible types
found   : java.util.Map.Entry<java.lang.Object,java.lang.Object>
required: java.util.Map.Entry<?,java.lang.Integer>
                for (Map.Entry<?,Integer> e : getEntries()) {
                                                        ^

Why isn't the enhanced for loop expression used as a context for applying the
type inference algorithm? Is this a bug or am I expected to explicitly provide an instantiation for
all method parameters?

At first, it seemed that the problem was related to the enhanced for loop expression; so I tried
The following workaround (whichdoesn't compile either):

public class Test {
    static <K,V> Iterable<Map.Entry<K,V>> getEntries() {return null;}    

    public static void main(String[] args) {
        Iterable<Map.Entry<?,Integer>> it = getEntries(); //should be a workaround
        for (Map.Entry<?,Integer> e : it) {
        }
    }
}

But, surprisingly, I found that this code (surprisingly) compiles:

public class Test {
    static <K,V> Iterable<Map.Entry<K,V>> getEntries() {return null;}    

    public static void main(String[] args) {
        Iterable<Map.Entry<String,Integer>> it = getEntries(); //should be a workaround
        for (Map.Entry<?,Integer> e : it) {
        }
    }
}

In other words it seems that the inference process only works with concrete types but not with wildcard types.
Is this problem due to a bug in the inference process?

Comments
EVALUATION A proposal: "either add for-each as assignment context considered by 15.12.2.8 or tweak 15.12.2.7 so that multiple dependent constraints are also taken into account." The enhanced-for statement is defined by translation to a basic for loop, so cannot be referred to in an assignment conversion context as such. The translation would have to be changed from 'I #i = Expression.iterator()' to 'Iterable<...> x = Expression; I #i = x.iterator();' where '...' is difficult to define. The alternative, inference in a method conversion context, is a long-standing request.
08-12-2010

EVALUATION Expanding the scope of type-inference is something that we will consider for 8.
26-10-2010