Skip to content

Commit af51bb8

Browse files
committed
Even more optimizing documentation lints? (3/2)
Avoid creating so many SessionGlobals
1 parent 506411d commit af51bb8

File tree

3 files changed

+114
-7
lines changed

3 files changed

+114
-7
lines changed

clippy_lints/src/doc/needless_doctest_main.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,7 @@ pub fn check(
6969
body: Some(block),
7070
..
7171
}) if ident.name == sym::main => {
72-
if !ignore {
73-
get_test_spans(&item, *ident, &mut test_attr_spans);
74-
}
72+
get_test_spans(&item, *ident, &mut test_attr_spans);
7573
let is_async = matches!(sig.header.coroutine_kind, Some(CoroutineKind::Async { .. }));
7674
let returns_nothing = match &sig.decl.output {
7775
FnRetTy::Default(..) => true,
@@ -86,13 +84,22 @@ pub fn check(
8684
// This main function should not be linted, we're done
8785
eligible = false;
8886
}
87+
// Return early if we're in an ignore codeblock, as
88+
// test_attr_in_doctest
89+
// won't do anything useful in these cases and we already have our
90+
// problematic function.
8991
},
9092
// Another function was found; this case is ignored for needless_doctest_main
9193
ItemKind::Fn(fn_) => {
9294
eligible = false;
93-
if !ignore {
94-
get_test_spans(&item, fn_.ident, &mut test_attr_spans);
95+
if ignore {
96+
// If ignore is active invalidating one lint,
97+
// and we already found another function thus
98+
// invalidating the other one, we have no
99+
// business continuing.
100+
return (false, test_attr_spans);
95101
}
102+
get_test_spans(&item, fn_.ident, &mut test_attr_spans);
96103
},
97104
// Tests with one of these items are ignored
98105
ItemKind::Static(..)
@@ -120,6 +127,17 @@ pub fn check(
120127

121128
let trailing_whitespace = text.len() - text.trim_end().len();
122129

130+
// We currently only test for "fn main". Checking for the real
131+
// entrypoint (with tcx.entry_fn(())) in each block would be unnecessarily
132+
// expensive, as those are probably intended and relevant. Same goes for
133+
// macros and other weird ways of declaring a main function.
134+
//
135+
// Also, as we only check for attribute names and don't do macro expansion,
136+
// we can check only for #[test]
137+
if !(text.contains("fn main") || text.contains("#[test]")) {
138+
return;
139+
}
140+
123141
// Because of the global session, we need to create a new session in a different thread with
124142
// the edition we need.
125143
let text = text.to_owned();

tests/ui/doc/needless_doctest_main.rs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
//@ check-pass
2-
31
#![warn(clippy::needless_doctest_main)]
42
//! issue 10491:
53
//! ```rust,no_test
@@ -19,4 +17,69 @@
1917
/// ```
2018
fn foo() {}
2119

20+
#[rustfmt::skip]
21+
/// Description
22+
/// ```rust
23+
/// fn main() {
24+
//~^ error: needless `fn main` in doctest
25+
/// let a = 0;
26+
/// }
27+
/// ```
28+
fn mulpipulpi() {}
29+
30+
#[rustfmt::skip]
31+
/// With a `#[no_main]`
32+
/// ```rust
33+
/// #[no_main]
34+
/// fn a() {
35+
/// let _ = 0;
36+
/// }
37+
/// ```
38+
fn pulpimulpi() {}
39+
40+
// Without a `#[no_main]` attribute
41+
/// ```rust
42+
/// fn a() {
43+
/// let _ = 0;
44+
/// }
45+
/// ```
46+
fn plumilupi() {}
47+
48+
#[rustfmt::skip]
49+
/// Additional function, shouldn't trigger
50+
/// ```rust
51+
/// fn additional_function() {
52+
/// let _ = 0;
53+
/// // Thus `fn main` is actually relevant!
54+
/// }
55+
/// fn main() {
56+
/// let _ = 0;
57+
/// }
58+
/// ```
59+
fn mlupipupi() {}
60+
61+
#[rustfmt::skip]
62+
/// Additional function AFTER main, shouldn't trigger
63+
/// ```rust
64+
/// fn main() {
65+
/// let _ = 0;
66+
/// }
67+
/// fn additional_function() {
68+
/// let _ = 0;
69+
/// // Thus `fn main` is actually relevant!
70+
/// }
71+
/// ```
72+
fn lumpimupli() {}
73+
74+
#[rustfmt::skip]
75+
/// Ignore code block, should not lint at all
76+
/// ```rust, ignore
77+
/// fn main() {
78+
//~^ error: needless `fn main` in doctest
79+
/// // Hi!
80+
/// let _ = 0;
81+
/// }
82+
/// ```
83+
fn mpulpilumi() {}
84+
2285
fn main() {}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: needless `fn main` in doctest
2+
--> tests/ui/doc/needless_doctest_main.rs:23:5
3+
|
4+
LL | /// fn main() {
5+
| _____^
6+
LL | |
7+
LL | | /// let a = 0;
8+
LL | | /// }
9+
| |_____^
10+
|
11+
= note: `-D clippy::needless-doctest-main` implied by `-D warnings`
12+
= help: to override `-D warnings` add `#[allow(clippy::needless_doctest_main)]`
13+
14+
error: needless `fn main` in doctest
15+
--> tests/ui/doc/needless_doctest_main.rs:77:5
16+
|
17+
LL | /// fn main() {
18+
| _____^
19+
LL | |
20+
LL | | /// // Hi!
21+
LL | | /// let _ = 0;
22+
LL | | /// }
23+
| |_____^
24+
25+
error: aborting due to 2 previous errors
26+

0 commit comments

Comments
 (0)