Add assert_is_empty lint#17149
Conversation
036738a to
d7911c9
Compare
This comment has been minimized.
This comment has been minimized.
d7911c9 to
4a8cdc6
Compare
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @dswij (or someone else) some time within the next two weeks. Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (
Why was this reviewer chosen?The reviewer was selected based on:
|
|
Lintcheck changes for 4d2c39f
This comment will be updated if you push new changes |
4a8cdc6 to
3af5d85
Compare
|
Just a note that it seems someone else has since had this idea at #17320 |
3af5d85 to
97e93cb
Compare
97e93cb to
7763bb8
Compare
|
Following up on Daniel’s note above: I reviewed #17320 and left the fuller gap analysis here: #17320 (comment). The useful implementation detail from that PR was the early The main differences from this side are intentional:
assert_eq!(items, [] as [T; 0]);
assert_ne!(items, [] as [T; 0]);That avoids type inference failures from a bare
One diagnostic wording difference that came up while comparing them: this PR now uses polarity-aware wording and explains why the replacement helps. For a non-empty check, this PR reports: The duplicate currently reports the same shape as: Both point in the same direction, but I think the wording here is clearer: the diagnostic names the actual state being checked, and the help text says that the replacement is useful because it shows the value on failure. |
|
@rustbot label lint-nominated |
|
This lint has been nominated for inclusion. |
|
As @kpreid notes on zulip, we should document the potential drawback of divulging what's inside the nonempty vector/string, which could contain sensitive information. |
7763bb8 to
adac632
Compare
|
Good point. I added a I looked for nearby precedent before changing behavior. The closest shape I found was documenting the tradeoff and recommending a narrow allow where the lint is not appropriate, rather than changing the lint to distinguish test and non-test assertions. For example, The new docs now call out that printing the asserted value can be undesirable outside tests, especially for very large values or values containing sensitive information. In those cases, the suggested fix is to keep the boolean assertion and allow this lint at that assertion. |
|
We do have an |
I don't think we should, but I don't tend to use asserts in non test code and I don't know of any specific use cases that you would hit this based on that. Worth releasing, or cratering and seeing if it gets any push back? |
adac632 to
dae36e6
Compare
|
It's totally ok as is. Let's see if the FCP gets us more comments though. |
Warn when assert macros without custom messages check collection emptiness in a way that hides the collection contents on failure. The lint suggests assert_eq/assert_ne forms for supported collections so failing tests print the unexpected value. Skip assertions that already provide a custom message, following the manual_assert_eq precedent that a message is a signal the author chose the diagnostic output.
dae36e6 to
4d2c39f
Compare
View all comments
changelog: new lint: [
assert_is_empty]fixes #17114
Adds a pedantic lint for
assert!anddebug_assert!calls without custom messages that only check whether a supported value is empty. The lint suggestsassert_eq!,assert_ne!,debug_assert_eq!, ordebug_assert_ne!forms so failures print the unexpected value.Rationale:
Boolean emptiness assertions only report that the predicate failed. In test failures, especially CI failures, that often leaves the developer without the collection contents needed to diagnose the problem. Comparing against an empty value gives the assertion machinery a value to print, and it also avoids hiding later content checks such as
assert_eq!(items[0], "bar")behind a precedingassert!(!items.is_empty())failure.Supported suggestions currently cover strings, slices, arrays, and
Vec. Other collection types are skipped when there is no compact empty-literal comparison or when the replacement assertion would not provide useful failure output.Implementation notes:
manual_assert_eqprecedent that a custom message is a signal that the author chose the diagnostic output.Vec<T>suggestions use[] as [T; 0]so the empty operand carries enough type information for bothassert_eq!andassert_ne!..as_slice()because direct comparison with[]does not compile for those receiver types.DebugandPartialEq.HashMap::new()may be worth revisiting, but this PR keeps the first version to compact empty-literal comparisons.New-lint checklist:
.stderrand.fixedfilescargo testpasses locallycargo dev update_lintscargo dev fmtValidation run locally:
cargo dev update_lintscargo dev fmtTESTNAME=assert_is_empty cargo uitestcargo test --test dogfoodcargo test