-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Add doc_examples_missing_item lint
#17766
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| use super::{DOC_EXAMPLES_MISSING_ITEM, is_public_api}; | ||
| use clippy_utils::attrs::is_proc_macro; | ||
| use clippy_utils::diagnostics::span_lint_and_help; | ||
| use clippy_utils::{is_lint_allowed, is_trait_impl_item, tokenize_with_text}; | ||
| use rustc_hir::def::DefKind; | ||
| use rustc_lexer::TokenKind; | ||
| use rustc_lint::LateContext; | ||
| use rustc_span::Ident; | ||
|
|
||
| pub(super) fn item_ident(cx: &LateContext<'_>, check_private_items: bool) -> Option<Ident> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. instead of this function being if..return None if..return None, how about we make this into an bigger if-let, since if you specify the case where you want the ident it is simpler to reason about for readers due to not having to deal with double negations, ... I in particularly stubled over
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, I expect the positive case if chain might get long but I saw elsewhere in clippy lints occasionally there are fairly large ones. Will rewrite shortly.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cleaned up, actually found a small duplication with another lint and cleaned both. Lmk if that is okay as part of this PR or whether it would be ideal to split it. |
||
| let hir_id = cx.last_node_with_lint_attrs; | ||
| let owner_id = hir_id.as_owner()?; | ||
| if !is_lint_allowed(cx, DOC_EXAMPLES_MISSING_ITEM, hir_id) | ||
| // Types and traits are skipped because examples often use them through a glob import without naming | ||
| // them, and telling which glob-imported names an example uses needs name resolution on every doctest. | ||
| && matches!( | ||
| cx.tcx.def_kind(owner_id), | ||
| DefKind::Fn | DefKind::AssocFn | DefKind::Const | DefKind::AssocConst | DefKind::Static { .. } | ||
| ) | ||
| && !is_trait_impl_item(cx, hir_id) | ||
| && !is_proc_macro(cx.tcx.hir_attrs(hir_id)) | ||
| && (check_private_items || is_public_api(cx, owner_id)) | ||
| { | ||
| cx.tcx.opt_item_ident(owner_id.to_def_id()) | ||
| } else { | ||
| None | ||
| } | ||
| } | ||
|
|
||
| pub(super) fn mentions(code: &str, ident: Ident) -> bool { | ||
| if !code.contains(ident.as_str()) { | ||
| return false; | ||
| } | ||
|
|
||
| tokenize_with_text(code).any(|(kind, text, _)| { | ||
| matches!(kind, TokenKind::Ident | TokenKind::RawIdent) | ||
| && text.strip_prefix("r#").unwrap_or(text) == ident.as_str() | ||
| }) | ||
| } | ||
|
Comment on lines
+30
to
+39
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looking at the lintcheck results, we might want to skip structs and traits as they would be trickier to handle, they all seem like false positives.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that this check on methods/functions has likely much lower false positives, but a few (6 our of 13) of the cases of interest in Diesel which I caught with dejadoc were on structs, therefore I would believe it still has value. @notriddle is there any particular acceptable pattern in clippy to say "check X, but only for item kinds in set Y", so that users may decide whether they want to enable this on any particular set of items? Or should it explode into a set of lints like
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You could use clippy.toml for that? https://doc.rust-lang.org/nightly/clippy/lint_configuration.html
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wasn't aware it was possible to configure each lint, I hadn't ever had to config it in a repo, thank you for pointing it out. I will familiarize with it and proceed as suggested.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added the configuration, by default parametrized as @Gri-ffin suggests, and optionally parametrizable to include all item kinds. @notriddle please do let me whether I have set it up correctly or I have missed using some of the intended patterns/methods.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don’t feel qualified to answer this question. I know Clippy has “restriction” lints that are allowed to flag harmless code, as long as the lint perform as advertised, but I’m not sure how open the team is to adding them.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I removed the configuration together with the struct, enum, union and trait support, so the lint now only covers functions, methods, constants and statics. Should be good to go now.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Gri-ffin do the more recent updates address the earlier issues you raised satisfactorily?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are yes, due to policy though you should find a reviewer in Here is the link to the policy: https://forge.rust-lang.org/policies/llm-usage.html
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I appreciate it, just wanted to make sure the lint is now as you would expect it to be. |
||
|
|
||
| pub(super) fn report(cx: &LateContext<'_>, ident: Ident) { | ||
| span_lint_and_help( | ||
| cx, | ||
| DOC_EXAMPLES_MISSING_ITEM, | ||
| cx.tcx.def_span(cx.last_node_with_lint_attrs.owner), | ||
| format!("none of the documentation examples mention `{ident}`"), | ||
| None, | ||
| "consider adding an example that uses this item", | ||
| ); | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this so big?!
needless_doctest_main.rsis less than a hundred lines of code and it’s doing a similar check to this one.View changes since the review
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I familiarized with the similar linting, refactored and trimmed down significantly. Thanks for the patience.