Skip to content

Commit 3745a3f

Browse files
committed
Even more optimizing documentation lints? (3/2)
Avoid creating so many SessionGlobals Improve filtering and account for spacing Actually return early
1 parent 506411d commit 3745a3f

File tree

3 files changed

+150
-4
lines changed

3 files changed

+150
-4
lines changed

clippy_lints/src/doc/needless_doctest_main.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ pub fn check(
7272
if !ignore {
7373
get_test_spans(&item, *ident, &mut test_attr_spans);
7474
}
75+
7576
let is_async = matches!(sig.header.coroutine_kind, Some(CoroutineKind::Async { .. }));
7677
let returns_nothing = match &sig.decl.output {
7778
FnRetTy::Default(..) => true,
@@ -90,9 +91,14 @@ pub fn check(
9091
// Another function was found; this case is ignored for needless_doctest_main
9192
ItemKind::Fn(fn_) => {
9293
eligible = false;
93-
if !ignore {
94-
get_test_spans(&item, fn_.ident, &mut test_attr_spans);
94+
if ignore {
95+
// If ignore is active invalidating one lint,
96+
// and we already found another function thus
97+
// invalidating the other one, we have no
98+
// business continuing.
99+
return (false, test_attr_spans);
95100
}
101+
get_test_spans(&item, fn_.ident, &mut test_attr_spans);
96102
},
97103
// Tests with one of these items are ignored
98104
ItemKind::Static(..)
@@ -120,6 +126,18 @@ pub fn check(
120126

121127
let trailing_whitespace = text.len() - text.trim_end().len();
122128

129+
// We currently only test for "fn main". Checking for the real
130+
// entrypoint (with tcx.entry_fn(())) in each block would be unnecessarily
131+
// expensive, as those are probably intended and relevant. Same goes for
132+
// macros and other weird ways of declaring a main function.
133+
//
134+
// Also, as we only check for attribute names and don't do macro expansion,
135+
// we can check only for #[test]
136+
137+
if !((text.contains("main") && text.contains("fn")) || 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: 94 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,98 @@
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+
85+
#[rustfmt::skip]
86+
/// Spaces in weird positions (including an \u{A0} after `main`)
87+
/// ```rust
88+
/// fn main (){
89+
//~^ error: needless `fn main` in doctest
90+
/// let _ = 0;
91+
/// }
92+
/// ```
93+
fn plumpiplupi() {}
94+
95+
/// 4 Functions, this should not lint because there are several function
96+
///
97+
/// ```rust
98+
/// fn a() {let _ = 0; }
99+
/// fn b() {let _ = 0; }
100+
/// fn main() { let _ = 0; }
101+
/// fn d() { let _ = 0; }
102+
/// ```
103+
fn pulmipulmip() {}
104+
105+
/// 3 Functions but main is first, should also not lint
106+
///
107+
///```rust
108+
/// fn main() { let _ = 0; }
109+
/// fn b() { let _ = 0; }
110+
/// fn c() { let _ = 0; }
111+
/// ```
112+
fn pmuplimulip() {}
113+
22114
fn main() {}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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: needless `fn main` in doctest
26+
--> tests/ui/doc/needless_doctest_main.rs:88:5
27+
|
28+
LL | /// fn main (){
29+
| _____^
30+
LL | |
31+
LL | | /// let _ = 0;
32+
LL | | /// }
33+
| |_____^
34+
35+
error: aborting due to 3 previous errors
36+

0 commit comments

Comments
 (0)