Subtype check error for lambda

82 views Asked by At

I am trying to implement a simple subtyping check for the checker-framework.
It does basically work, but I get an error related to lambda-usage that I don't understand.

I've created a simple test-project on github: checkerfw-test so that anyone can easily reproduce the issue.

The typesystem that I use is much like the RegEx example in the docs/src.
Here's a link to my types:

  • IdDomainObject is the top type
  • IdUser, IdCustomer are the custom types that should not be assignable to each other
  • IdBottom is the bottom type

The compilation of my testFromCallable2() function:

static class GenericHolder<T> {
    public T field;
}

public static <T> GenericHolder<T> fromCallable(final Callable<? extends T> callable) {
    GenericHolder<T> result = new GenericHolder<T>();
    try {
        result.field = callable.call();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}

public void testFromCallable2() {
    GenericHolder<@IdCustomer Long> tmp2 = fromCallable(() -> {
                final @IdCustomer Long customerId = toCustomerId(1);
                return customerId;
            }
    );
}

fails with this error-message:

      GenericHolder<@IdCustomer Long> tmp2 = fromCallable(() -> {

   required: @IdDomainObject GenericHolder<@IdCustomer Long>

I don't think this should fail, because the lambda returns exactly the specified type.

The test-source also contains a function testFromCallable1, which does the same, just without a lambda and this code works:

public void testFromCallable1() {
    GenericHolder<@IdCustomer Long> tmp = fromCallable(new Callable<@IdCustomer Long>() {
        @Override
        public @IdCustomer Long call() throws Exception {
            final @IdCustomer Long customerId = toCustomerId(1);
            return customerId;
        }
    });
}

What am I missing?

Note:
I am just beginning to use the subtype-checker, so I think I did not understand all the docs about subtyping yet: e.g. maybe I have just set some wrong values for some of the annotations on my type-definitions (e.g. @ImplicitFor, @DefaultFor, ...)

I am using checker-framework version 2.2.0

1

There are 1 answers

0
Suzanne Millstein On BEST ANSWER

The Checker Framework doesn't yet fully implement Java 8 type inference. See Issue #979. You can work around this limitation by explicitly specifying the type argument to fromCallable.

GenericHolder<@IdCustomer Long> tmp2 = this.<@IdCustomer Long>fromCallable(() -> {
           final @IdCustomer Long customerId = toCustomerId(1);
            return customerId;
        }
);

testFromCallable1 doesn't issue the error because it doesn't use Java 8 type inference.