Skip to content

Commit

Permalink
Auto merge of #4729 - rust-lang:needless-doc-main-syn, r=<try>
Browse files Browse the repository at this point in the history
Use syn in needless_doctest_main lint

changelog: none

This fixes #4698 by only linting non-empty `fn main()`s. This is not a perfect solution, but I don't want to omit linting if any macro call or attribute is detected, as that would result in many false negatives.
  • Loading branch information
bors committed Nov 28, 2019
2 parents dbdd75a + 1077c23 commit fcd7e14
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 6 deletions.
7 changes: 4 additions & 3 deletions clippy_lints/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ matches = "0.1.7"
pulldown-cmark = "0.6.0"
quine-mc_cluskey = "0.2.2"
regex-syntax = "0.6"
semver = "0.9.0"
serde = { version = "1.0", features = ["derive"] }
smallvec = { version = "1", features = ["union"] }
syn = { version = "1.0", features = ["full"] }
toml = "0.5.3"
unicode-normalization = "0.1"
semver = "0.9.0"
# NOTE: cargo requires serde feat in its url dep
# see <https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864>
# cargo requires serde feat in its url dep
# see https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864
url = { version = "2.1.0", features = ["serde"] }

[features]
Expand Down
26 changes: 23 additions & 3 deletions clippy_lints/src/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -342,9 +342,29 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
safety_header
}

fn check_code(cx: &LateContext<'_, '_>, text: &str, span: Span) {
if text.contains("fn main() {") {
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
// check a syn Item for non-empty `fn main() { .. }`
fn is_default_main_fn(item: &syn::Item) -> bool {
match item {
syn::Item::Fn(syn::ItemFn { ref sig, ref block, .. }) => {
!block.stmts.is_empty()
&& sig.ident == "main"
&& match sig.output {
syn::ReturnType::Default => true,
syn::ReturnType::Type(_, ref ty) => match **ty {
syn::Type::Tuple(syn::TypeTuple { ref elems, .. }) => elems.is_empty(),
_ => false,
},
}
},
_ => false,
}
}

fn check_code(cx: &LateContext<'_, '_>, code: &str, span: Span) {
if let Ok(file) = syn::parse_file(code) {
if file.items.iter().any(is_default_main_fn) {
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main() {}` in doctest");
}
}
}

Expand Down
27 changes: 27 additions & 0 deletions tests/ui/needless_doc_main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/// This method does nothing. It's just there for testing.
///
/// # Examples:
///
/// ```text,ignore
/// This is not Rust code
/// Just check that parsing won't crash
/// R€fridger@tør.
/// ```
///
/// ```
/// fn main() {
/// let this_is_linted = 42u8;
/// assert_eq!(this_is_linted / 2, 21);
/// }
/// ```
///
/// ```
/// #[allow(unused)]
/// const I = 1;
/// fn main() {
/// // this main method contains no code and is thus not linted.
/// }
/// ```
fn main() {
// nothing to see here, move along.
}
10 changes: 10 additions & 0 deletions tests/ui/needless_doc_main.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: needless `fn main() {}` in doctest
--> $DIR/needless_doc_main.rs:12:4
|
LL | /// fn main() {
| ^^^^^^^^^^^^
|
= note: `-D clippy::needless-doctest-main` implied by `-D warnings`

error: aborting due to previous error

0 comments on commit fcd7e14

Please sign in to comment.