Guava type inference problems

Dan Smith daniel.smith at oracle.com
Thu Nov 21 11:23:11 PST 2013


Looks to me like this should succeed.  I'll include my "by hand" inference notes in the bug.

—Dan

On Nov 21, 2013, at 7:10 AM, Vicente-Arturo Romero-Zaldivar <vicente.romero at oracle.com> wrote:

> Hi Jonathan,
> 
> Thanks for the bug report. I have filed bug entry [1] to track it.
> 
> Very nice report, it provides two examples with a minimum difference 
> between them that uncover a possible bug.
> 
> Thanks,
> Vicente
> 
> [1] https://bugs.openjdk.java.net/browse/JDK-8028774
> 
> On 19/11/13 23:37, Jonathan Ross wrote:
>> Hello again,
>> 
>> my problem below is probably also due to a well understood change to the
>> type inference rules, and I am sorry if this has all been said and done
>> before, but I really want to understand what's going on here.
>> 
>> Paraphrasing some production 1.7 code using guava, I have essentially the
>> following:
>> 
>> import java.util.Collection;
>> import java.util.List;
>> 
>> abstract class TypeTest {
>> 
>>     interface I {}
>> 
>>     public Collection<? extends I> excludeFrom(Collection<? extends I>
>> include,
>>             Collection<? extends I> exclude) {
>>         return copyOf(filter(include, not(in(exclude))));
>>     }
>> 
>>     interface Predicate<T> {
>>         boolean apply(T t);
>>     }
>> 
>>     abstract <T> Predicate<T> in(Collection<? extends T> target);
>>     abstract <T> Predicate<T> not(Predicate<T> aPredicate);
>>     abstract <E> List<E> copyOf(Iterable<? extends E> elements);
>> 
>>     abstract <T> Iterable<T> filter(Iterable<T> unfiltered, Predicate<?
>> super T> predicate);
>> }
>> 
>> 
>> When I compile this with b115, the compiler bails out, with
>> 
>> TypeTest.java:9: error: no suitable method found for copyOf(Iterable<CAP#1>)
>> 
>>         return copyOf(filter(include, not(in(exclude))));
>> 
>>                ^
>> 
>>     method TypeTest.<E#1>copyOf(Iterable<? extends E#1>) is not applicable
>> 
>>       (cannot infer type-variable(s) E#1,T#1,T#2,T#3
>> 
>>         (argument mismatch; Iterable<CAP#2> cannot be converted to
>> Iterable<? extends CAP#2>))
>> 
>>     method TypeTest.<E#2>copyOf(Collection<? extends E#2>) is not applicable
>> 
>>       (no instance(s) of type variable(s) T#1,T#2,T#3 exist so that
>> Iterable<T#1> conforms to Collection<? extends E#2>)
>> 
>>   where E#1,T#1,T#2,T#3,E#2 are type-variables:
>> 
>>     E#1 extends Object declared in method <E#1>copyOf(Iterable<? extends
>> E#1>)
>> 
>>     T#1 extends Object declared in method
>> <T#1>filter(Iterable<T#1>,Predicate<? super T#1>)
>> 
>>     T#2 extends Object declared in method <T#2>not(Predicate<T#2>)
>> 
>>     T#3 extends Object declared in method <T#3>in(Collection<? extends T#3>)
>> 
>>     E#2 extends Object declared in method <E#2>copyOf(Collection<? extends
>> E#2>)
>> 
>>   where CAP#1,CAP#2 are fresh type-variables:
>> 
>>     CAP#1 extends I from capture of ? extends I
>> 
>>     CAP#2 extends I from capture of ? extends I
>> 
>> 1 error
>> 
>> But if I replace excludeFrom with
>> 
>>     public Collection<? extends I> filter(Collection<? extends I> include,
>>             Collection<? extends I> exclude) {
>>         Iterable<? extends I> myFiltered = filter(include,
>> not(in(exclude)));
>>         return copyOf(myFiltered);
>>     }
>> 
>> compilation succeeds. What gives?
>> 
>> Thanks in advance,
>> 
>> Jonathan Ross
>> 
> 
> 



More information about the lambda-dev mailing list