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

Incorrect type argument inference #5070

Closed
blablubbabc opened this issue Mar 2, 2022 · 4 comments
Closed

Incorrect type argument inference #5070

blablubbabc opened this issue Mar 2, 2022 · 4 comments
Assignees

Comments

@blablubbabc
Copy link

blablubbabc commented Mar 2, 2022

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
	});
}
@smillst
Copy link
Member

smillst commented Mar 2, 2022

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 smillst changed the title Wildcards of different type captures are not considered compatible Incorrect type argument inference Mar 2, 2022
@blablubbabc
Copy link
Author

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.

@smillst
Copy link
Member

smillst commented Mar 2, 2022

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

@smillst
Copy link
Member

smillst commented May 21, 2024

This test case was fixed with #979.

@smillst smillst closed this as completed May 21, 2024
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

No branches or pull requests

2 participants