Guava type inference problems

Vicente-Arturo Romero-Zaldivar vicente.romero at oracle.com
Thu Nov 21 06:10:44 PST 2013


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