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 typeIdUser
,IdCustomer
are the custom types that should not be assignable to each otherIdBottom
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
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
.testFromCallable1
doesn't issue the error because it doesn't use Java 8 type inference.