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

Add missing_assert_message lint #10362

Merged
merged 10 commits into from
Mar 8, 2023

Conversation

unexge
Copy link
Contributor

@unexge unexge commented Feb 16, 2023

Fixes #6207.

changelog: new lint: [missing_assert_message]: A new lint for checking assertions that doesn't have a custom panic message.
#10362

r? @llogiq

@rustbot
Copy link
Collaborator

rustbot commented Feb 16, 2023

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @llogiq (or someone else) soon.

Please see the contribution instructions for more information.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Feb 16, 2023
Copy link
Contributor

@llogiq llogiq left a comment

Choose a reason for hiding this comment

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

Great work! I think the macro stuff is really tricky.

I have but a few small doc suggestions and I'll have to look up if we need an msrv.

clippy_lints/src/missing_assert_message.rs Outdated Show resolved Hide resolved
clippy_lints/src/missing_assert_message.rs Outdated Show resolved Hide resolved
clippy_lints/src/missing_assert_message.rs Show resolved Hide resolved
clippy_lints/src/missing_assert_message.rs Outdated Show resolved Hide resolved
Comment on lines 222 to 223
debug_assert!(lit_kind.is_numeric());
debug_assert!(lit_kind.is_numeric(), "`lit_kind` should be numeric");
lit_suffix_length(lit_kind)
Copy link
Member

Choose a reason for hiding this comment

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

My two cents: these changes display the very problem with this lint.
It encourages people to just add some kind of assert-message to silent the lint, but the message provides zero information.

If foo.is_numeric() returns false and blows up an assert, I already know that foo is not numeric and that this is problematic.
Why would would I want to waste time and add the same exact information "foo should be numeric" again, in a textual form (which just adds additional maintenance burden because now I have to additionally update the message every time I change the variable name, etc..) ?

IMO it would be good to add an additional message to the lint, something along the lines of
help: try to describe why the failing assert is problematic. The inserted assert-message should be more about the why is it important to know that this failed and not what exactly failed here, because the code inside the assert already conveys that.

Copy link
Contributor

Choose a reason for hiding this comment

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

I agree that the messages provided here are a bit meh. However, I would not say that this is a problem with the lint; we simply have no way of knowing whether an assert message will satisfy. However, having them at all will at least put them under the eyes of a potential reviewer. Also I think your point should be added to the lint's documentation.

Perhaps tne lint should be put in restriction instead of pedantic.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes you're right about the messages, since we are not very familiar with the codebase we tried to come up with messages by quickly looking at the assertion but it was hard to come up with good messages.
I've added a help message and updated the lint's description.
Didn't know about restriction, it makes more sense for this lint. I've reverted the "dogfood" commit, I believe someone with more familiarity with the codebase can enable the lint and come up with good assert messages in a follow-up PR.

@llogiq
Copy link
Contributor

llogiq commented Feb 16, 2023

I just looked and assert!s allowed messages back in 1.0.0, so no MSRV necessary.

@@ -911,6 +912,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(size_of_ref::SizeOfRef));
store.register_late_pass(|_| Box::new(multiple_unsafe_ops_per_block::MultipleUnsafeOpsPerBlock));
store.register_late_pass(|_| Box::new(extra_unused_type_parameters::ExtraUnusedTypeParameters));
store.register_pre_expansion_pass(|| Box::<missing_assert_message::MissingAssertMessage>::default());
Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately we don't want to be adding more pre expansion passes because it comes with a good number of bugs - #6610, it would want to be a late pass

We do have some utilities that would help out there: find_assert_args and find_assert_eq_args. Usage would be similar to

let Some(macro_call) = root_macro_call_first_node(cx, e) else { return };
let is_debug = match cx.tcx.get_diagnostic_name(macro_call.def_id) {
Some(sym::debug_assert_macro) => true,
Some(sym::assert_macro) => false,
_ => return,
};
let Some((condition, panic_expn)) = find_assert_args(cx, e, macro_call.expn) else { return };

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We started with a late pass and find_assert_args functions, but I think there was a recent change in the compiler and assert macros expand to something else than find_assert_args expects. So those functions don't return the correct PanicExpn, we tried to fix it but couldn't do it :) I'll give it another go!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So it seems like starting from Rust 1.52 assert_{eq,ne} macros use panicking::assert_failed instead of panic! (See assert_eq in 1.52 and in 1.51).

a2502da addresses Rust 1.52 changes
569fa96 converts this lint to a late lint pass

@bors
Copy link
Contributor

bors commented Feb 23, 2023

☔ The latest upstream changes (presumably #10392) made this pull request unmergeable. Please resolve the merge conflicts.

@unexge unexge force-pushed the missing-assert-message-lint branch from cc616a4 to 569fa96 Compare February 24, 2023 00:30
@unexge
Copy link
Contributor Author

unexge commented Mar 2, 2023

/ping 😄 I believe all the comments are addressed and it's ready for another round of review

@llogiq
Copy link
Contributor

llogiq commented Mar 3, 2023

@Alexendoo since you commented on the implementation, do you have an idea on how to get this to work as a LateLintPass?

@Alexendoo
Copy link
Member

It's working as a late pass from the latest commit, it looks good to me at a glance

Copy link
Contributor

@llogiq llogiq left a comment

Choose a reason for hiding this comment

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

This looks good to me, I only have a last small doc suggestion.

/// Without a good custom message, it'd be hard to understand what went wrong when the assertion fails.
/// A good custom message should be more about why the failure of the assertion is problematic
/// and not what is failed because the assertion already conveys that.
///
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should have a ### Known Problems section that admits we cannot check the assert messages for quality, and perhaps a link to some docs or guidelines?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added the Known Problems section but couldn't find a good doc to link. The best thing I can find is the answers to https://softwareengineering.stackexchange.com/questions/301652/purpose-of-assertion-messages. What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

Nah, let's not link to a site where the content could change at will. In that case, just leave the quality unspecified.

@bors
Copy link
Contributor

bors commented Mar 7, 2023

☔ The latest upstream changes (presumably #10415) made this pull request unmergeable. Please resolve the merge conflicts.

@unexge unexge force-pushed the missing-assert-message-lint branch from 9c5ec69 to b554ff4 Compare March 8, 2023 08:52
@llogiq
Copy link
Contributor

llogiq commented Mar 8, 2023

Thank you!

@bors r+

@bors
Copy link
Contributor

bors commented Mar 8, 2023

📌 Commit b554ff4 has been approved by llogiq

It is now in the queue for this repository.

@bors
Copy link
Contributor

bors commented Mar 8, 2023

⌛ Testing commit b554ff4 with merge 216aefb...

@bors
Copy link
Contributor

bors commented Mar 8, 2023

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: llogiq
Pushing 216aefb to master...

@bors bors merged commit 216aefb into rust-lang:master Mar 8, 2023
@unexge unexge deleted the missing-assert-message-lint branch March 8, 2023 09:22
@mickvangelderen
Copy link
Contributor

mickvangelderen commented Sep 22, 2023

Would it be possible to not trigger this lint in testing code? In tests the assert expression usually suffices but outside of tests the additional message is much more likely to be exposed to a non-developer.

This is done for other lints such as unwrap_used.

@unexge
Copy link
Contributor Author

unexge commented Sep 22, 2023

Hey @mickvangelderen, that should already be the case. There might be some cases we fail to identify as a test function though, could you please share the code if possible?

@mickvangelderen
Copy link
Contributor

@unexge ah, I only read the lint documentation, not the code. Perhaps it should be added because I misjudged the false positive rate of this lint based on the current description.

@unexge
Copy link
Contributor Author

unexge commented Sep 27, 2023

@mickvangelderen Yes, that's definitely a good point! I'll submit a PR. Thanks!

bors added a commit that referenced this pull request Sep 28, 2023
Mention that `missing_assert_message` lint ignores test functions

Updates `missing_assert_message`'s docs to reflect that it ignores test functions as pointed out by `@mickvangelderen` in #10362 (comment)

---

changelog: [`missing_assert_message`]: Update docs to reflect this lint ignores test functions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Lint assert! without message
7 participants