Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
phoenix384 opened this issue Apr 23, 2019 · 3 comments · Fixed by #257
Closed

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

phoenix384 opened this issue Apr 23, 2019 · 3 comments · Fixed by #257

Comments

@phoenix384
Copy link
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.

@berolinux
Copy link

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
Copy link
Contributor Author

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.

@vaukai
Copy link

vaukai commented Jul 5, 2022

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
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants