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

Investigate Kotlin 2.1 compiler warnings for contracts #4371

Open
1 task
marcphilipp opened this issue Mar 5, 2025 · 4 comments
Open
1 task

Investigate Kotlin 2.1 compiler warnings for contracts #4371

marcphilipp opened this issue Mar 5, 2025 · 4 comments

Comments

@marcphilipp
Copy link
Member

marcphilipp commented Mar 5, 2025

The Kotlin contracts introduced in #1866 cause the following warnings after bumping apiVersion and languageVersion to 2.1 on the marc/jdk17 branch.

w: junit-jupiter-api/src/main/kotlin/org/junit/jupiter/api/Assertions.kt:414:9 Wrong invocation kind 'EXACTLY_ONCE' for 'executable: () -> R' specified, the actual invocation kind is 'AT_MOST_ONCE'.
w: junit-jupiter-api/src/main/kotlin/org/junit/jupiter/api/Assertions.kt:442:9 Wrong invocation kind 'EXACTLY_ONCE' for 'executable: () -> R' specified, the actual invocation kind is 'AT_MOST_ONCE'.
w: junit-jupiter-api/src/main/kotlin/org/junit/jupiter/api/Assertions.kt:466:9 Wrong invocation kind 'EXACTLY_ONCE' for 'executable: () -> R' specified, the actual invocation kind is 'AT_MOST_ONCE'.
w: junit-jupiter-api/src/main/kotlin/org/junit/jupiter/api/Assertions.kt:490:9 Wrong invocation kind 'EXACTLY_ONCE' for 'executable: () -> R' specified, the actual invocation kind is 'AT_MOST_ONCE'.

These warnings can be reproduced by running ./gradlew :junit-jupiter-api:compileKotlin --rerun

They are currently not treated as errors:

compileKotlin {
// https://github.com/junit-team/junit5/issues/4371
compilerOptions.allWarningsAsErrors = false
}

Deliverables

  • Resolve the warnings or suppress them if they're false positives
@awelless
Copy link
Contributor

awelless commented Mar 6, 2025

At first glance the errors look like false positives.
It seem the reason is that all these lambda calls are wrapped into a try-catch block, which makes the compiler assume a passed lambda may not return.

This KT issue perfectly describes the reason of the error in the evaluateAndWrap method.

assertThrows is more interesting. Either the compiler doesn't understand that any Throwable is rethrown immediately or it doesn't support contract interop with Java at all.

@marcphilipp
Copy link
Member Author

So you think we can safely suppress these warnings? If so, what's the "category" to use with the @Suppress annotation?

@awelless
Copy link
Contributor

awelless commented Mar 29, 2025

I investigated this issue more in detail.

First, it's possible to suppress them with @Suppress("WRONG_INVOCATION_KIND") on the method level.

Second, I perhaps wouldn't do it.
When it comes to assertThrows callsInPlace docs require the function to be inline, which isn't the case there. So it'd be our responsibility to guarantee this contract.
The error in evaluateAndWrap looks valid. If you take this method in isolation, it's possible for executable() to throw, while the method itself doesn't throw anything. So, it's possible to end up with an invalid state, and EXACTLY_ONCE is not guaranteed there.

There was an example of a potential change to assertDoesNotThrow, but it doesn't support suspend functions.

@marcphilipp
Copy link
Member Author

@awelless Thanks for taking a closer look!

If you take this method in isolation, it's possible for executable() to throw, while the method itself doesn't throw anything. So, it's possible to end up with an invalid state, and EXACTLY_ONCE is not guaranteed there.

But isn't executable "invoked exactly one time" even if it throws? Or does EXACTLY_ONCE mean that it's invoked completely, i.e. without throwing an exception?

IIUC, you wouldn't suppress the warnings but relax the contract to use AT_MOST_ONCE for executable parameters, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants