checker-framework icon indicating copy to clipboard operation
checker-framework copied to clipboard

Incorrect type argument inference

Open blablubbabc opened this issue 3 years ago • 3 comments
trafficstars

I am using the Gradle plugin (v 0.6.8) to invoke the CheckerFramework (v 3.21.2).

Simplified reproduction example:

public class Test {

	public List<? extends @NonNull String> getStrings() {
		return new ArrayList<>();
	}

	public static class Other {

		private Test other;

		public Other(Test other) {
			this.other = other;
		}

		public interface Provider<R> {
			public R get();
		}

		private <T> T invoke(Provider<T> provider) {
			return provider.get();
		}

		public List<? extends @NonNull String> getStrings() {
			return invoke(() -> {
				return other.getStrings(); // Error
			});
		}
	}
}

This compiles fine, but CF complains. CF error:

[return] incompatible types in return.

				return other.getStrings(); // Error
				                       ^
  type of expression: @UnknownKeyFor List<capture#980[ extends @UnknownKeyFor String super @KeyForBottom Void]>

  method return type: @UnknownKeyFor List<capture#871[ extends @UnknownKeyFor String super @UnknownKeyFor Void]>

My expectation would have been that if the return type is List<? extends String> and I invoke some method that returns a List<? extends String> (or any other kind of list with a element type that satisfies the declared lower and upper bounds), I should be able to forward the result of that. But CF considers those 2 lists incompatible because their element types involve different captures.

Edit: With an explicitly specified type for the Provider lambda the error is gone:

public List<? extends @NonNull String> getStrings() {
	return this.<@NonNull List<? extends @NonNull String>>invoke(() -> {
		return other.getStrings(); // Error
	});
}

blablubbabc avatar Mar 02 '22 16:03 blablubbabc

Thanks for reporting! I agree this shouldn't be an error. The problem isn't that the captures aren't comparable, but rather that the method type argument inferred for invoke is incorrect. We are currently working on fixing type argument inference; see #979.

smillst avatar Mar 02 '22 17:03 smillst

Thanks for reporting! I agree this shouldn't be an error. The problem isn't that the captures aren't comparable, but rather that the method type argument inferred for invoke is incorrect. We are currently working on fixing type argument inference; see #979.

Yeah, I saw that ticket and thought they might be related, since the issue goes away once I explicitly specify the otherwise inferred type, but I wasn't sure. I hope you don't mind if I dump all/some of the issues that I encounter with CF here. Feel free to close them as duplicates if they are already tracked by some other ticket. It's sometimes difficult for me to figure out if some error reported by CF is a false-positive, if that matches the description of some existing ticket, or if it is actually an issue with my code.

blablubbabc avatar Mar 02 '22 17:03 blablubbabc

We appreciate bug reports even if they turn out to be duplicates!

smillst avatar Mar 02 '22 17:03 smillst

This test case was fixed with #979.

smillst avatar May 21 '24 18:05 smillst