Skip to content

Matchers.anyOf: inference variable has incompatible bounds with Java >8 #256

Closed
@phoenix384

Description

@phoenix384
Contributor

The following code sample works with OpenJDK 8 but does not compile with OpenJDK 11:

public class SimpleTest {
	@Test
	public void test() {
		List<String> list = new ArrayList<>();
		assertThat(list, anyOf(hasItem("a"), hasItem("b")));
	}
}

Compiling with Java 11 fails with

    [javac]     method Assert.<T#1>assertThat(String,T#1,Matcher<? super T#1>) is not applicable
    [javac]       (cannot infer type-variable(s) T#1
    [javac]         (actual and formal argument lists differ in length))
    [javac]     method Assert.<T#2>assertThat(T#2,Matcher<? super T#2>) is not applicable
    [javac]       (inference variable T#3 has incompatible bounds
    [javac]         lower bounds: String,Object
    [javac]         lower bounds: String,Object)
    [javac]   where T#1,T#2,T#3 are type-variables:
    [javac]     T#1 extends Object declared in method <T#1>assertThat(String,T#1,Matcher<? super T#1>)
    [javac]     T#2 extends Object declared in method <T#2>assertThat(T#2,Matcher<? super T#2>)
    [javac]     T#3 extends Object declared in method <T#3>hasItem(T#3)

If the first argument of the Matchers.anyOf methods would be changed from Matcher to Matcher<? super T> (like in Matchers.allOf), it would work.

Activity

berolinux

berolinux commented on May 5, 2019

@berolinux

Even after applying #257, building hamcrest with OpenJDK 12.0.1 fails with

./org/hamcrest/core/AnyOf.java:44: error: no suitable method found for anyOf(List<Matcher<? super T#1>>)
        return anyOf(Arrays.asList(matchers));
               ^
    method AnyOf.<T#2>anyOf(Iterable<Matcher<? super T#2>>) is not applicable
      (inference variable T#3 has incompatible bounds
        equality constraints: Matcher<? super CAP#1>
        lower bounds: Matcher<? super T#1>)
    method AnyOf.<T#1>anyOf(Matcher<? super T#1>...) is not applicable
      (cannot infer type-variable(s) T#1
        (varargs mismatch; no instance(s) of type variable(s) T#3 exist so that List<T#3> conforms to Matcher<? super T#1>))
  where T#1,T#2,T#3 are type-variables:
    T#1 extends Object declared in method <T#1>anyOf(Matcher<? super T#1>...)
    T#2 extends Object declared in method <T#2>anyOf(Iterable<Matcher<? super T#2>>)
    T#3 extends Object declared in method <T#3>asList(T#3...)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object super: T#1 from capture of ? super T#1
./org/hamcrest/core/CombinableMatcher.java:60: error: incompatible types: Matcher<CAP#1> cannot be converted to Matcher<? super CAP#2>
      return new CombinableMatcher<>(first).and(other);
                                                ^
  where X is a type-variable:
    X extends Object declared in class CombinableBothMatcher
  where CAP#1,CAP#2 are fresh type-variables:
    CAP#1 extends Object super: X from capture of ? super X
    CAP#2 extends Object super: X from capture of ? super X
./org/hamcrest/core/CombinableMatcher.java:79: error: incompatible types: Matcher<CAP#1> cannot be converted to Matcher<? super CAP#2>
      return new CombinableMatcher<>(first).or(other);
                                               ^
  where X is a type-variable:
    X extends Object declared in class CombinableEitherMatcher
  where CAP#1,CAP#2 are fresh type-variables:
    CAP#1 extends Object super: X from capture of ? super X
    CAP#2 extends Object super: X from capture of ? super X
./org/hamcrest/text/IsEqualCompressingWhiteSpace.java:52: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static Matcher<String> equalToIgnoringWhiteSpace(String expectedString) {
                                  ^
./org/hamcrest/core/AllOf.java:54: error: no suitable method found for allOf(List<Matcher<? super T#1>>)
        return allOf(Arrays.asList(matchers));
               ^
    method AllOf.<T#2>allOf(Iterable<Matcher<? super T#2>>) is not applicable
      (inference variable T#3 has incompatible bounds
        equality constraints: Matcher<? super CAP#1>
        lower bounds: Matcher<? super T#1>)
    method AllOf.<T#1>allOf(Matcher<? super T#1>...) is not applicable
      (cannot infer type-variable(s) T#1
        (varargs mismatch; no instance(s) of type variable(s) T#3 exist so that List<T#3> conforms to Matcher<? super T#1>))
  where T#1,T#2,T#3 are type-variables:
    T#1 extends Object declared in method <T#1>allOf(Matcher<? super T#1>...)
    T#2 extends Object declared in method <T#2>allOf(Iterable<Matcher<? super T#2>>)
    T#3 extends Object declared in method <T#3>asList(T#3...)
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object super: T#1 from capture of ? super T#1
./org/hamcrest/core/IsCollectionContaining.java:42: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <T> Matcher<Iterable<? super T>> hasItem(Matcher<? super T> itemMatcher) {
                                                   ^
./org/hamcrest/core/IsCollectionContaining.java:59: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <T> Matcher<Iterable<? super T>> hasItem(T item) {
                                                   ^
./org/hamcrest/core/IsCollectionContaining.java:78: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <T> Matcher<Iterable<T>> hasItems(Matcher<? super T>... itemMatchers) {
                                           ^
./org/hamcrest/core/IsCollectionContaining.java:96: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <T> Matcher<Iterable<T>> hasItems(T... items) {
                                           ^
./org/hamcrest/Matchers.java:1204: warning: [dep-ann] deprecated item is not annotated with @Deprecated
  public static <T> org.hamcrest.Matcher<T> isIn(java.util.Collection<T> collection) {
                                            ^
./org/hamcrest/Matchers.java:1219: warning: [dep-ann] deprecated item is not annotated with @Deprecated
  public static <T> org.hamcrest.Matcher<T> isIn(T[] elements) {
                                            ^
./org/hamcrest/Matchers.java:1235: warning: [dep-ann] deprecated item is not annotated with @Deprecated
  public static <T> org.hamcrest.Matcher<T> isOneOf(T... elements) {
                                            ^
./org/hamcrest/Matchers.java:1380: warning: [dep-ann] deprecated item is not annotated with @Deprecated
  public static Matcher<java.lang.String> equalToIgnoringWhiteSpace(java.lang.String expectedString) {
                                          ^
./org/hamcrest/Matchers.java:1430: warning: [dep-ann] deprecated item is not annotated with @Deprecated
  public static Matcher<java.lang.String> isEmptyOrNullString() {
                                          ^
./org/hamcrest/Matchers.java:1442: warning: [dep-ann] deprecated item is not annotated with @Deprecated
  public static Matcher<java.lang.String> isEmptyString() {
                                          ^
./org/hamcrest/collection/IsArrayContainingInOrder.java:54: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <E> Matcher<E[]> arrayContaining(E... items) {
                                   ^
./org/hamcrest/collection/IsArrayContainingInOrder.java:75: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <E> Matcher<E[]> arrayContaining(Matcher<? super E>... itemMatchers) {
                                   ^
./org/hamcrest/collection/IsArrayContainingInOrder.java:76: error: incompatible types: inference variable E#1 has incompatible bounds
        return arrayContaining(asList(itemMatchers));
                              ^
    equality constraints: E#2
    lower bounds: List<T>
  where E#1,E#2,T are type-variables:
    E#1 extends Object declared in method <E#1>arrayContaining(E#1...)
    E#2 extends Object declared in method <E#2>arrayContaining(Matcher<? super E#2>...)
    T extends Object declared in method <T>asList(T...)
./org/hamcrest/collection/IsArrayContainingInOrder.java:92: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <E> Matcher<E[]> arrayContaining(List<Matcher<? super E>> itemMatchers) {
                                   ^
./org/hamcrest/collection/IsArrayContainingInOrder.java:17: warning: [dep-ann] deprecated item is not annotated with @Deprecated
public class IsArrayContainingInOrder<E> extends TypeSafeMatcher<E[]> {
       ^
./org/hamcrest/collection/ArrayMatching.java:70: error: incompatible types: inference variable E#1 has incompatible bounds
      return arrayContainingInAnyOrder(asList(itemMatchers));
                                      ^
    equality constraints: E#2
    lower bounds: List<T>
  where E#1,E#2,T are type-variables:
    E#1 extends Object declared in method <E#1>arrayContainingInAnyOrder(E#1...)
    E#2 extends Object declared in method <E#2>arrayContainingInAnyOrder(Matcher<? super E#2>...)
    T extends Object declared in method <T>asList(T...)
./org/hamcrest/collection/IsArrayContainingInAnyOrder.java:61: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <E> Matcher<E[]> arrayContainingInAnyOrder(Matcher<? super E>... itemMatchers) {
                                   ^
./org/hamcrest/collection/IsArrayContainingInAnyOrder.java:62: error: incompatible types: inference variable E#1 has incompatible bounds
        return arrayContainingInAnyOrder(Arrays.asList(itemMatchers));
                                        ^
    equality constraints: E#2
    lower bounds: List<T>
  where E#1,E#2,T are type-variables:
    E#1 extends Object declared in method <E#1>arrayContainingInAnyOrder(E#1...)
    E#2 extends Object declared in method <E#2>arrayContainingInAnyOrder(Matcher<? super E#2>...)
    T extends Object declared in method <T>asList(T...)
./org/hamcrest/collection/IsArrayContainingInAnyOrder.java:83: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <E> Matcher<E[]> arrayContainingInAnyOrder(Collection<Matcher<? super E>> itemMatchers) {
                                   ^
./org/hamcrest/collection/IsArrayContainingInAnyOrder.java:105: warning: [dep-ann] deprecated item is not annotated with @Deprecated
    public static <E> Matcher<E[]> arrayContainingInAnyOrder(E... items) {
                                   ^
./org/hamcrest/collection/IsIterableContainingInAnyOrder.java:101: error: incompatible types: inference variable T#1 has incompatible bounds
        return containsInAnyOrder(Arrays.asList(itemMatchers));
                                 ^
    equality constraints: T#2
    lower bounds: List<T#3>
  where T#1,T#2,T#3 are type-variables:
    T#1 extends Object declared in method <T#1>containsInAnyOrder(T#1...)
    T#2 extends Object declared in method <T#2>containsInAnyOrder(Matcher<? super T#2>...)
    T#3 extends Object declared in method <T#3>asList(T#3...)
./org/hamcrest/collection/IsIterableContainingInRelativeOrder.java:102: error: incompatible types: inference variable E#1 has incompatible bounds
        return containsInRelativeOrder(asList(itemMatchers));
                                      ^
    equality constraints: E#2
    lower bounds: List<T>
  where E#1,E#2,T are type-variables:
    E#1 extends Object declared in method <E#1>containsInRelativeOrder(E#1...)
    E#2 extends Object declared in method <E#2>containsInRelativeOrder(Matcher<? super E#2>...)
    T extends Object declared in method <T>asList(T...)
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
9 errors
18 warnings
phoenix384

phoenix384 commented on May 7, 2019

@phoenix384
ContributorAuthor

The intention was to make it possible to use anyOf from Java 11 code and not to make Hamcrest compilable with Java 11.
Moreover these errors do not relate to the code I changed.
Either way, my PR is an improvement, since now the method signature is the same as in allOf.

added a commit that references this issue on May 7, 2019
5f54700
vaukai

vaukai commented on Jul 5, 2022

@vaukai

The intention was to make it possible to use anyOf from Java 11 code and not to make Hamcrest compilable with Java 11.

Gentoo has a patch making it compile even with jdk 17.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      Participants

      @berolinux@phoenix384@vaukai

      Issue actions

        Matchers.anyOf: inference variable has incompatible bounds with Java >8 · Issue #256 · hamcrest/JavaHamcrest