1
votes

When i try to compile this cut-down example with a compiler from JDK 9, 10, or 11:

public class UpperBounder {
    public static void main(String[] args) {
        print(Stream.of("a", "z", "b").collect(Collectors.toCollection(TreeSet::new)));
    }

    static void print(Set<?> set) {
        System.out.println(set);
    }
}

I get this error:

error: incompatible types: inferred type does not conform to upper bound(s)

print(Stream.of("a", "z", "b").collect(Collectors.toCollection(TreeSet::new)));
^

inferred: INT#1
upper bound(s): Collection<String>,Set<?>,Object
where INT#1 is an intersection type:
INT#1 extends Object,Set<?>,Collection<String>

When i try to compile it with JDK 1.8.0_121, i get a different error. But when i or a colleague try to compile it with JDK 1.8.0_05, 1.8.0_20, 1.8.0_40, or 1.8.0_45, it compiles fine!

Replacing TreeSet::new with () -> new TreeSet<>() makes this compile without errors on all versions.

I think this program is clearly sound: the argument to print will be a TreeSet<String>, which conforms to Set<?>. Moreover, the error message makes no sense to me: an intersection type which is Object, Set<?>, and Collection<String> should conform to upper bounds which are Collection<String>, Set<?>, and Object!

What is going on? Is this a bug? Or is this how type inference is supposed to work? Why did it work before? How can i make it work again (without using a lambda instead of a method reference)?

1
It probably is a bug. In the java bug database, there's a whole bunch of type inference ones (there's a couple about intersecting types which may or may not apply here), many of which are still open, some fixed in JDK9, and a small portion backported to 8. For what it's worth, I can reproduce yours in javac 10.0.2, but not Eclipse's compiler ecj 3.14.0.v20180528 - NPras

1 Answers

1
votes

This looks like bug: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8219318 As at 16/07/2019 Oracle has confirmed that they can reproduce this bug, but does not have a fix for it yet.

Both your test case and the one in the bug database can be reproduced using Oracle 1.8.0_191, both work fine in all tested versions using ecj (Eclipse).