eisop / checker-framework

Pluggable type-checking for Java
https://eisop.github.io/
Other
15 stars 16 forks source link

#738 breaks a handful of our tests #757

Open cpovirk opened 2 months ago

cpovirk commented 2 months ago
  found   : @NonNull Foo<capture#02 extends @NonNull Foo<capture#02>>
  required: @Nullable Foo<? extends @NonNull Object>

It looks to me like the found type meets the requirements of the required type, so I'm not sure exactly where the problem lies.

I'll try to minimize that in the next couple days so that I can send you an actual repro.

cpovirk commented 2 months ago

Interestingly, that error arises only(?) in locations that previously had this error, which we had suppressed:

error: [type.invalid.conflicting.annos] invalid type: conflicting annotations [@NonNull, @Nullable] in type "@NonNull @Nullable Foo<capture#02 extends @NonNull @Nullable Foo<capture#02>>"

I think I'm close to a self-contained repro, but I'm posting that little bit for now so that I can close a couple windows I have open about it :)

cpovirk commented 2 months ago
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

@NullMarked
class Eisop757 {
  @SuppressWarnings("nullness:return.type.incompatible")
  <T> @NonNull T nullCheck(@Nullable T reference) {
    return reference;
  }

  void foo(Foo<? extends Bar<?>> foo) {
    Bar<?> cell = nullCheck(foo.bar());
  }

  interface Foo<T extends Bar<T>> {
    @Nullable T bar();
  }

  interface Bar<T> {}
}
/usr/local/google/home/cpovirk/code/Eisop757.java:13: error: [assignment.type.incompatible] incompatible types in assignment.
    Bar<?> cell = nullCheck(foo.bar());
                           ^
  found   : @NonNull Bar<capture#01 extends @NonNull Bar<capture#01>>
  required: @Nullable Bar<? extends @NonNull Object>
1 error
cpovirk commented 2 months ago

Interestingly, that error arises only(?) in locations that previously had this error, which we had suppressed:

The old error is gone, at least :) So #738 hasn't actually increased the number of errors, just changed the kind of error that we see, undoing our old suppressions.

wmdietl commented 1 month ago

@cpovirk Sorry for not commenting on this (since a comment in a document when you filed this).

I cannot reproduce a difference between before #738 and after. I also tried typetools release checker-framework-3.42.0. I tried your version and the following CF-only version:

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

class Eisop757 {
  @SuppressWarnings("nullness:return.type.incompatible")
  <T extends Object> @NonNull T nullCheck(@Nullable T reference) {
    return reference;
  }

  void foo(Foo<? extends Bar<?>> foo) {
    Bar<?> cell = nullCheck(foo.bar());
  }

  interface Foo<T extends Bar<T>> {
    @Nullable T bar();
  }

  interface Bar<T extends Object> {}
}

Are you using the CF Nullness Checker or the JSpecify reference checker?