Skip to content

Commit 92f5c73

Browse files
author
Andre Bogus
committed
Fix needless_doctest_main span
1 parent 0f4a3fe commit 92f5c73

File tree

4 files changed

+42
-9
lines changed

4 files changed

+42
-9
lines changed

clippy_lints/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ semver = "0.9.0"
3333
# NOTE: cargo requires serde feat in its url dep
3434
# see <https://github.com/rust-lang/rust/pull/63587#issuecomment-522343864>
3535
url = { version = "2.1.0", features = ["serde"] }
36+
bytecount = "0.6.0"
3637

3738
[features]
3839
deny-warnings = []

clippy_lints/src/doc.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::utils::{get_trait_def_id, implements_trait, is_entrypoint_fn, match_type, paths, return_ty, span_lint};
1+
use crate::utils::{
2+
get_trait_def_id, implements_trait, is_entrypoint_fn, match_type, paths, return_ty, snippet_opt, span_lint,
3+
};
4+
use bytecount::count;
25
use if_chain::if_chain;
36
use itertools::Itertools;
47
use rustc::lint::in_external_macro;
@@ -357,9 +360,9 @@ fn check_attrs<'a>(cx: &LateContext<'_, '_>, valid_idents: &FxHashSet<String>, a
357360

358361
match (previous.0, current.0) {
359362
(Text(previous), Text(current)) => {
360-
let mut previous = previous.to_string();
361-
previous.push_str(&current);
362-
Ok((Text(previous.into()), previous_range))
363+
let text = (previous.to_string() + &current).into();
364+
let range = previous_range.start..current_range.end;
365+
Ok((Text(text), range))
363366
},
364367
(previous, current) => Err(((previous, previous_range), (current, current_range))),
365368
}
@@ -413,6 +416,12 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
413416
};
414417
let (begin, span) = spans[index];
415418
if in_code {
419+
let lo = span.lo() + BytePos::from_usize(range.start - begin);
420+
let span = Span::new(
421+
lo,
422+
lo + BytePos::from_usize(text.len() + count(text.as_bytes(), b'\n') * 4),
423+
span.ctxt(),
424+
);
416425
check_code(cx, &text, span);
417426
} else {
418427
// Adjust for the beginning of the current `Event`
@@ -429,8 +438,14 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
429438
static LEAVE_MAIN_PATTERNS: &[&str] = &["static", "fn main() {}", "extern crate", "async fn main() {"];
430439

431440
fn check_code(cx: &LateContext<'_, '_>, text: &str, span: Span) {
432-
if text.contains("fn main() {") && !LEAVE_MAIN_PATTERNS.iter().any(|p| text.contains(p)) {
433-
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
441+
if let Some(comment) = snippet_opt(cx, span) {
442+
if let Some(offset) = comment.find("fn main() {") {
443+
if !LEAVE_MAIN_PATTERNS.iter().any(|p| text.contains(p)) {
444+
let lo = span.lo() + BytePos::from_usize(offset);
445+
let span = Span::new(lo, lo + BytePos::from_usize("fn main()".len()), span.ctxt());
446+
span_lint(cx, NEEDLESS_DOCTEST_MAIN, span, "needless `fn main` in doctest");
447+
}
448+
}
434449
}
435450
}
436451

tests/ui/needless_doc_main.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,17 @@
88
/// unimplemented!();
99
/// }
1010
/// ```
11+
///
12+
/// This should also lint, and have correct span
13+
///
14+
/// ```
15+
/// use std::io::Write as _;
16+
///
17+
/// fn main() {
18+
/// let x = String::new();
19+
/// write!(x, "Hallo");
20+
/// }
21+
/// ```
1122
fn bad_doctest() {}
1223

1324
/// # Examples

tests/ui/needless_doc_main.stderr

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
error: needless `fn main` in doctest
2-
--> $DIR/needless_doc_main.rs:7:4
2+
--> $DIR/needless_doc_main.rs:7:5
33
|
44
LL | /// fn main() {
5-
| ^^^^^^^^^^^^
5+
| ^^^^^^^^^
66
|
77
= note: `-D clippy::needless-doctest-main` implied by `-D warnings`
88

9-
error: aborting due to previous error
9+
error: needless `fn main` in doctest
10+
--> $DIR/needless_doc_main.rs:17:5
11+
|
12+
LL | /// fn main() {
13+
| ^^^^^^^^^
14+
15+
error: aborting due to 2 previous errors
1016

0 commit comments

Comments
 (0)