Skip to content

Commit 21bab8b

Browse files
Add new lint doc_include_without_cfg
1 parent 73bad36 commit 21bab8b

File tree

6 files changed

+64
-2
lines changed

6 files changed

+64
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5440,6 +5440,7 @@ Released 2018-09-13
54405440
[`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type
54415441
[`disallowed_types`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types
54425442
[`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression
5443+
[`doc_include_without_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_include_without_cfg
54435444
[`doc_lazy_continuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation
54445445
[`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes
54455446
[`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
77

8-
[There are over 700 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
8+
[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
99

1010
Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html).
1111
You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category.

book/src/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
A collection of lints to catch common mistakes and improve your
77
[Rust](https://github.com/rust-lang/rust) code.
88

9-
[There are over 700 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
9+
[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
1010

1111
Lints are divided into categories, each with a default [lint
1212
level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
148148
crate::doc::TEST_ATTR_IN_DOCTEST_INFO,
149149
crate::doc::TOO_LONG_FIRST_DOC_PARAGRAPH_INFO,
150150
crate::doc::UNNECESSARY_SAFETY_DOC_INFO,
151+
crate::doc::DOC_INCLUDE_WITHOUT_CFG_INFO,
151152
crate::double_parens::DOUBLE_PARENS_INFO,
152153
crate::drop_forget_ref::DROP_NON_DROP_INFO,
153154
crate::drop_forget_ref::FORGET_NON_DROP_INFO,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::source::snippet_opt;
3+
use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, AttrStyle, Attribute};
4+
use rustc_errors::Applicability;
5+
use rustc_lint::LateContext;
6+
use rustc_span::sym;
7+
8+
use super::DOC_INCLUDE_WITHOUT_CFG;
9+
10+
pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) {
11+
for attr in attrs {
12+
if let AttrKind::Normal(ref normal) = attr.kind
13+
&& normal.item.path == sym::doc
14+
&& let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args
15+
&& !attr.span.contains(meta.span)
16+
&& let Some(snippet) = snippet_opt(cx, attr.span)
17+
&& let Some(start) = snippet.find('[')
18+
&& let Some(end) = snippet.rfind(']')
19+
{
20+
let snippet = &snippet[start + 1..end];
21+
span_lint_and_sugg(
22+
cx,
23+
DOC_INCLUDE_WITHOUT_CFG,
24+
attr.span,
25+
"included a file in documentation unconditionally",
26+
"use `cfg_attr(doc, doc = \"...\")`",
27+
format!(
28+
"#{}[cfg_attr(doc, {snippet})]",
29+
if attr.style == AttrStyle::Inner { "!" } else { "" }
30+
),
31+
Applicability::MachineApplicable,
32+
);
33+
}
34+
}
35+
}

clippy_lints/src/doc/mod.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ use std::ops::Range;
3333
use url::Url;
3434

3535
mod empty_line_after;
36+
mod include_in_doc_without_cfg;
3637
mod link_with_quotes;
3738
mod markdown;
3839
mod missing_headers;
@@ -532,6 +533,29 @@ declare_clippy_lint! {
532533
"empty line after doc comments"
533534
}
534535

536+
declare_clippy_lint! {
537+
/// ### What it does
538+
/// Checks if included files in doc comments are included only for `cfg(doc)`.
539+
///
540+
/// ### Why is this bad?
541+
/// These files are not useful for compilation but will still be included.
542+
/// Also, if any of these non-source code file is updated, it will trigger a
543+
/// recompilation.
544+
///
545+
/// ### Example
546+
/// ```ignore
547+
/// #![doc = include_str!("some_file.md")]
548+
/// ```
549+
/// Use instead:
550+
/// ```no_run
551+
/// #![cfg_attr(doc, doc = include_str!("some_file.md"))]
552+
/// ```
553+
#[clippy::version = "1.84.0"]
554+
pub DOC_INCLUDE_WITHOUT_CFG,
555+
suspicious,
556+
"check if files included in documentation are behind `cfg(doc)`"
557+
}
558+
535559
pub struct Documentation {
536560
valid_idents: FxHashSet<String>,
537561
check_private_items: bool,
@@ -690,6 +714,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
690714
Some(("fake".into(), "fake".into()))
691715
}
692716

717+
include_in_doc_without_cfg::check(cx, attrs);
693718
if suspicious_doc_comments::check(cx, attrs) || empty_line_after::check(cx, attrs) || is_doc_hidden(attrs) {
694719
return None;
695720
}

0 commit comments

Comments
 (0)