Skip to content

Conversation

@dkhalanskyjb
Copy link
Collaborator

No description provided.

@dkhalanskyjb dkhalanskyjb requested a review from murfel October 17, 2025 08:20
@dkhalanskyjb dkhalanskyjb force-pushed the dkhalanskyjb/fix-some-warnings branch from 047a527 to 2c2bb7c Compare October 20, 2025 10:34
@murfel
Copy link
Contributor

murfel commented Oct 20, 2025

Any advice on how to review this?

E.g. which parts were not the obvious fix for a warning?

@dkhalanskyjb
Copy link
Collaborator Author

The majority of changed lines follow one of several patterns, so it's enough to understand an edit once, and then the rest of the instances become clear as well.

Examples:

  • Removed @Suppress: if no new warnings/errors surfaced, then this @Suppress was already redundant, as its whole purpose is to hide warnings and errors we disagree with.
  • Removed type annotation on a function call: likewise, this is just historical baggage from when Kotlin was worse at inferring types.
  • @Suppress("DEPRECATION") added to tests that check the behavior of a deprecated API (using which causes a warning) whose correctness we still want to ensure.
  • Added ? to types coming from Java that the compiler now knows can be null.

There are a few non-trivial fixes, but most changes are just boilerplate.

@murfel
Copy link
Contributor

murfel commented Oct 20, 2025

Could you describe the process for these two? The process itself is partly proof of correctness (and the other part is the clean compilation).

E.g. which @Suppress / type annotations did you attempt removing?

Removed @Suppress: if no new warnings/errors surfaced, then this @Suppress was already redundant, as its whole purpose is to hide warnings and errors we disagree with.

Removed type annotation on a function call: likewise, this is just historical baggage from when Kotlin was worse at inferring types.

@dkhalanskyjb
Copy link
Collaborator Author

Sure.

For @Suppress, the process was:

  1. Observe a warning like "suppressing errors may break the behavior".
  2. Attempt removing the @Suppress.
  3. If a new error appears that was hidden by the @Suppress, restore the @Suppress.

Steps 2 and 3 can be replaced with just looking at the code or preliminary knowledge or assumptions, so some @Suppress annotations have been left untouched.

For removing type annotations: when I was fixing some warnings in a file, I also went through the suggestion provided by the IDE, considered if applying them is proper, and then I either did that or reported a broken suggestion to the IDE team.

Copy link
Contributor

@murfel murfel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for taking this cleanup on! I was pretty annoyed with all the warnings.

? in my comments mean please provide context/reference/proof for the correctness of the change.


I'd also like a prove of completeness of certain replacements. E.g. as if with the publc modifier in test, the proof is empty grep in Idea. The proof can come just as a confirmation statement, "grep for xxx in directory yyy is empty", then I can check it in O(1).

For now I'm not sure when you did or didn't aim for completeness.

I also not sure how you discovered the warnings. Did you use compilation warnings only? If I run "inspect project" in Idea, I see many more warnings, some of them similar to the ones fixed here.


Just FYI: here's a context to which changes are easier to check during review

Easy to check

Removals

  • @Suppress
  • inferable type parameters
  • not-null assertions (!!)
  • public modifiers from tests
  • imports

These removals are easy because if the CI passes after the change, then the change is valid. Hence, I don't need to think about it.

And other things

  • Rename the unused parameter in the catch clause to _

Harder to check

  • Adding suppresses (since we don't have a check "this suppress doesn't suppress anything")
  • Loosening the type to nullable (adding ?)
  • Adding not-null assertion (!!)
  • Changes not triggered by inspections (If I undo the change, I don't see any static warning that triggers me)

val mutex = Mutex(true) // locked mutex
val job = launch(start = CoroutineStart.UNDISPATCHED) {
expect(2)
select<String> { // suspends
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

select<String> - <String> can also be removed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how you discovered the other entries for the "Remove explicit type arguments" inspection, by hand or by following warnings. If the latter, not sure why this and other few cases were missed. Possibly also clean them up?

finish(4)
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Newline

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a checkbox in Idea, "ensure every saved file ends with a line break"

finish(4)
}

@Suppress("DEPRECATION")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add // Mutex.onLock, since there's no hint neither on github, nor in Idea after the suppress has been added

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here and in other entries of @Suppress("DEPRECATION")

*/
class JobStatesTest : TestBase() {
@Test
public fun testNormalCompletion() = runTest {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's another 15 entries for public fun in common/test, and most of them don't need the public modifier. Could you get rid of them as well?

@Test
fun testExceptionFromWithinTimeout() = runTest {
expect(1)
@Suppress("UNREACHABLE_CODE")
Copy link
Contributor

@murfel murfel Oct 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add // expectUnreached() here and everywhere else

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you happen to know why this particular expectUnreached() triggered the inspection, but many others didn't?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expectUnreached() is not some specific construct, it's just a function call. The inspection gets triggered when a value of type Nothing gets returned. Nothing is a type with no values, and you can only return it by throwing an exception or having an infinite loop in your code. Here, withTimeout returns Nothing, because its body never produces a normal value, and the compiler can recognize that. If we add a type parameter (withTimeout<Int>, for example), the compiler won't be able to do that.

}
}

/** Tests that even the dispatch timeout of `0` is fine if all the dispatches go through the same scheduler. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why rearranging the file?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To have one Suppress for a group of tests.


# We are cheating a bit by not having android.jar on R8's library classpath. Ignore those warnings.
-ignorewarnings
-dontwarn
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try running :kotlinx-coroutines-android:runR8 with and without this change, and the difference should be clear. ignorewarnings doesn't suppress the warnings we're not interested in.

-checkdiscard class kotlinx.coroutines.DebugKt
-checkdiscard class kotlinx.coroutines.internal.StackTraceRecoveryKt
-checkdiscard class kotlinx.coroutines.debug.DebugProbesKt
-checkdiscard class kotlinx.coroutines.debug.internal.DebugProbesKt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no kotlinx.coroutines.debug.DebugProbesKt now, ever since it DebugProbes.kt got moved to the internal package, so the rule was meaningless before the change.

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

Successfully merging this pull request may close these issues.

3 participants