Skip to content

Commit 00f6841

Browse files
committed
Use a simpler way to generate these doc comments
1 parent 99b16ae commit 00f6841

5 files changed

+71
-92
lines changed

clippy_lints/src/doc/doc_suspicious_footnotes.rs

Lines changed: 23 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
use clippy_utils::diagnostics::span_lint_and_then;
22
use rustc_errors::Applicability;
3-
use rustc_lint::{LateContext, LintContext};
3+
use rustc_hir::{AttrStyle, Attribute};
4+
use rustc_lint::LateContext;
45

56
use std::ops::Range;
67

78
use super::{DOC_SUSPICIOUS_FOOTNOTES, Fragments};
89

9-
pub fn check(cx: &LateContext<'_>, doc: &str, range: Range<usize>, fragments: &Fragments<'_>) {
10+
pub fn check(cx: &LateContext<'_>, doc: &str, range: Range<usize>, fragments: &Fragments<'_>, attrs: &[Attribute]) {
1011
for i in doc[range.clone()]
1112
.bytes()
1213
.enumerate()
@@ -29,6 +30,8 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range<usize>, fragments: &F
2930
found
3031
})
3132
.or(fragments.fragments.last())
33+
&& let Some((last_doc_attr, last_doc_attr_str)) =
34+
attrs.iter().rev().find_map(|attr| Some((attr, attr.doc_str()?)))
3235
{
3336
let span = fragments.span(cx, start..end).unwrap_or(this_fragment.span);
3437
span_lint_and_then(
@@ -37,55 +40,28 @@ pub fn check(cx: &LateContext<'_>, doc: &str, range: Range<usize>, fragments: &F
3740
span,
3841
"looks like a footnote ref, but has no matching footnote",
3942
|diag| {
40-
let applicability = Applicability::HasPlaceholders;
41-
let start_of_md_line = doc.as_bytes()[..start]
42-
.iter()
43-
.rposition(|&c| c == b'\n' || c == b'\r')
44-
.unwrap_or(0);
45-
let end_of_md_line = doc.as_bytes()[start..]
46-
.iter()
47-
.position(|&c| c == b'\n' || c == b'\r')
48-
.unwrap_or(doc.len() - start)
49-
+ start;
50-
let span_md_line = fragments
51-
.span(cx, start_of_md_line..end_of_md_line)
52-
.unwrap_or(this_fragment.span);
53-
let span_whole_line = cx.sess().source_map().span_extend_to_line(span_md_line);
54-
if let Ok(mut pfx) = cx
55-
.sess()
56-
.source_map()
57-
.span_to_snippet(span_whole_line.until(span_md_line))
58-
&& let Ok(mut sfx) = cx
59-
.sess()
60-
.source_map()
61-
.span_to_snippet(span_md_line.shrink_to_hi().until(span_whole_line.shrink_to_hi()))
62-
{
63-
let mut insert_before = String::new();
64-
let mut insert_after = String::new();
65-
let span = if this_fragment.kind == rustc_resolve::rustdoc::DocFragmentKind::RawDoc
66-
&& (!pfx.is_empty() || !sfx.is_empty())
67-
{
68-
if (pfx.trim() == "#[doc=" || pfx.trim() == "#![doc=") && sfx.trim() == "]" {
69-
// try to use per-line doc fragments if that's what the author did
70-
pfx.push('"');
71-
sfx.insert(0, '"');
72-
span_whole_line.shrink_to_hi()
73-
} else {
74-
// otherwise, replace the whole line with the result
75-
pfx = String::new();
76-
sfx = String::new();
77-
insert_before = format!(r#"r###"{}"#, this_fragment.doc);
78-
r####""###"####.clone_into(&mut insert_after);
79-
span_md_line
80-
}
43+
if last_doc_attr.is_doc_comment() {
44+
let pfx = if last_doc_attr.style() == AttrStyle::Outer {
45+
"///"
8146
} else {
82-
span_whole_line.shrink_to_hi()
47+
"//!"
8348
};
8449
diag.span_suggestion_verbose(
85-
span,
50+
last_doc_attr.span().shrink_to_hi(),
8651
"add footnote definition",
87-
format!("{insert_before}\n{pfx}{sfx}\n{pfx}{label}: <!-- description -->{sfx}\n{pfx}{sfx}{insert_after}", label = &doc[start..end]),
88-
applicability,
52+
format!("\n{pfx}\n{pfx}{label}: <!-- description -->", label = &doc[start..end]),
53+
Applicability::HasPlaceholders,
54+
);
55+
} else if let Some(vspan) = last_doc_attr.value_span() {
56+
diag.span_suggestion_verbose(
57+
vspan,
58+
"add footnote definition",
59+
format!(
60+
"r#\"{doc}\n\n{label}: <!-- description -->\"#",
61+
doc = last_doc_attr_str,
62+
label = &doc[start..end],
63+
),
64+
Applicability::HasPlaceholders,
8965
);
9066
}
9167
},

clippy_lints/src/doc/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
862862
doc: &doc,
863863
fragments: &fragments,
864864
},
865+
attrs,
865866
))
866867
}
867868

@@ -942,6 +943,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
942943
events: Events,
943944
doc: &str,
944945
fragments: Fragments<'_>,
946+
attrs: &[Attribute],
945947
) -> DocHeaders {
946948
// true if a safety header was found
947949
let mut headers = DocHeaders::default();
@@ -1187,7 +1189,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
11871189
continue;
11881190
}
11891191
text_to_check.push((text, range.clone(), code_level));
1190-
doc_suspicious_footnotes::check(cx, doc, range, &fragments);
1192+
doc_suspicious_footnotes::check(cx, doc, range, &fragments, attrs);
11911193
}
11921194
}
11931195
FootnoteReference(_) => {}

tests/ui/doc_suspicious_footnotes.fixed

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
#![warn(clippy::doc_suspicious_footnotes)]
22
#![allow(clippy::needless_raw_string_hashes)]
33
//! This is not a footnote[^1].
4-
//!
5-
//! [^1]: <!-- description -->
6-
//!
74
//~^ doc_suspicious_footnotes
85
//!
96
//! This is not a footnote[^either], but it doesn't warn.
@@ -17,11 +14,10 @@
1714
//! This is a footnote[^2].
1815
//!
1916
//! [^2]: hello world
17+
//!
18+
//![^1]: <!-- description -->
2019

2120
/// This is not a footnote[^1].
22-
///
23-
/// [^1]: <!-- description -->
24-
///
2521
//~^ doc_suspicious_footnotes
2622
///
2723
/// This is not a footnote[^either], but it doesn't warn.
@@ -35,16 +31,15 @@
3531
/// This is a footnote[^2].
3632
///
3733
/// [^2]: hello world
34+
///
35+
///[^1]: <!-- description -->
3836
pub fn footnotes() {
3937
// test code goes here
4038
}
4139

4240
pub struct Foo;
4341
impl Foo {
44-
#[doc = r###"This is not a footnote[^1].
45-
46-
[^1]: <!-- description -->
47-
"###]
42+
#[doc = r#"This is not a footnote[^1]."#]
4843
//~^ doc_suspicious_footnotes
4944
#[doc = r#""#]
5045
#[doc = r#"This is not a footnote[^either], but it doesn't warn."#]
@@ -57,11 +52,13 @@ impl Foo {
5752
#[doc = r#""#]
5853
#[doc = r#"This is a footnote[^2]."#]
5954
#[doc = r#""#]
60-
#[doc = r#"[^2]: hello world"#]
55+
#[doc = r#"[^2]: hello world
56+
57+
[^1]: <!-- description -->"#]
6158
pub fn footnotes() {
6259
// test code goes here
6360
}
64-
#[doc = r###"This is not a footnote[^1].
61+
#[doc = r#"This is not a footnote[^1].
6562

6663
This is not a footnote[^either], but it doesn't warn.
6764

@@ -76,31 +73,26 @@ impl Foo {
7673
[^2]: hello world
7774

7875

79-
[^1]: <!-- description -->
80-
"###]
76+
[^1]: <!-- description -->"#]
8177
//~^^^^^^^^^^^^^^ doc_suspicious_footnotes
8278
pub fn footnotes2() {
8379
// test code goes here
8480
}
8581
#[cfg_attr(
8682
not(FALSE),
87-
doc = r###"This is not a footnote[^1].
83+
doc = r#"This is not a footnote[^1].
8884

8985
This is not a footnote[^either], but it doesn't warn.
9086

91-
[^1]: <!-- description -->
92-
"###
87+
[^1]: <!-- description -->"#
9388
//~^ doc_suspicious_footnotes
9489
)]
9590
pub fn footnotes3() {
9691
// test code goes here
9792
}
9893
}
9994

100-
#[doc = r###"This is not a footnote[^1].
101-
102-
[^1]: <!-- description -->
103-
"###]
95+
#[doc = r"This is not a footnote[^1]."]
10496
//~^ doc_suspicious_footnotes
10597
#[doc = r""]
10698
#[doc = r"This is not a footnote[^either], but it doesn't warn."]
@@ -113,7 +105,9 @@ This is not a footnote[^either], but it doesn't warn.
113105
#[doc = r""]
114106
#[doc = r"This is a footnote[^2]."]
115107
#[doc = r""]
116-
#[doc = r"[^2]: hello world"]
108+
#[doc = r#"[^2]: hello world
109+
110+
[^1]: <!-- description -->"#]
117111
pub fn footnotes_attrs() {
118112
// test code goes here
119113
}

tests/ui/doc_suspicious_footnotes.stderr

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ LL | //! This is not a footnote[^1].
88
= help: to override `-D warnings` add `#[allow(clippy::doc_suspicious_footnotes)]`
99
help: add footnote definition
1010
|
11-
LL ~ //! This is not a footnote[^1].
12-
LL + //!
13-
LL + //! [^1]: <!-- description -->
14-
LL + //!
11+
LL ~ //! [^2]: hello world
12+
LL + //!
13+
LL + //![^1]: <!-- description -->
1514
|
1615

1716
error: looks like a footnote ref, but has no matching footnote
@@ -22,10 +21,9 @@ LL | /// This is not a footnote[^1].
2221
|
2322
help: add footnote definition
2423
|
25-
LL ~ /// This is not a footnote[^1].
26-
LL + ///
27-
LL + /// [^1]: <!-- description -->
28-
LL + ///
24+
LL ~ /// [^2]: hello world
25+
LL + ///
26+
LL + ///[^1]: <!-- description -->
2927
|
3028

3129
error: looks like a footnote ref, but has no matching footnote
@@ -36,10 +34,9 @@ LL | #[doc = r#"This is not a footnote[^1]."#]
3634
|
3735
help: add footnote definition
3836
|
39-
LL ~ #[doc = r###"This is not a footnote[^1].
37+
LL ~ #[doc = r#"[^2]: hello world
4038
LL +
41-
LL + [^1]: <!-- description -->
42-
LL ~ "###]
39+
LL ~ [^1]: <!-- description -->"#]
4340
|
4441

4542
error: looks like a footnote ref, but has no matching footnote
@@ -56,7 +53,7 @@ LL | | "]
5653
|
5754
help: add footnote definition
5855
|
59-
LL ~ #[doc = r###"This is not a footnote[^1].
56+
LL ~ #[doc = r#"This is not a footnote[^1].
6057
LL +
6158
LL + This is not a footnote[^either], but it doesn't warn.
6259
LL +
@@ -71,8 +68,7 @@ LL +
7168
LL + [^2]: hello world
7269
LL +
7370
LL +
74-
LL + [^1]: <!-- description -->
75-
LL ~ "###]
71+
LL ~ [^1]: <!-- description -->"#]
7672
|
7773

7874
error: looks like a footnote ref, but has no matching footnote
@@ -83,12 +79,11 @@ LL | doc = "This is not a footnote[^1].\n\nThis is not a footnote[^eithe
8379
|
8480
help: add footnote definition
8581
|
86-
LL ~ doc = r###"This is not a footnote[^1].
82+
LL ~ doc = r#"This is not a footnote[^1].
8783
LL +
8884
LL + This is not a footnote[^either], but it doesn't warn.
8985
LL +
90-
LL + [^1]: <!-- description -->
91-
LL + "###
86+
LL + [^1]: <!-- description -->"#
9287
|
9388

9489
error: looks like a footnote ref, but has no matching footnote
@@ -99,10 +94,9 @@ LL | #[doc = r"This is not a footnote[^1]."]
9994
|
10095
help: add footnote definition
10196
|
102-
LL ~ #[doc = r###"This is not a footnote[^1].
97+
LL ~ #[doc = r#"[^2]: hello world
10398
LL +
104-
LL + [^1]: <!-- description -->
105-
LL ~ "###]
99+
LL ~ [^1]: <!-- description -->"#]
106100
|
107101

108102
error: aborting due to 6 previous errors

tests/ui/doc_suspicious_footnotes_include.stderr

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,22 @@ LL | This is not a footnote[^1].
88
= help: to override `-D warnings` add `#[allow(clippy::doc_suspicious_footnotes)]`
99
help: add footnote definition
1010
|
11-
LL ~ This is not a footnote[^1].
11+
LL + r#"This is not a footnote[^1].
1212
LL +
13-
LL + [^1]: <!-- description -->
13+
LL + This is not a footnote[^either], but it doesn't warn.
14+
LL +
15+
LL + This is not a footnote\[^1], but it also doesn't warn.
16+
LL +
17+
LL + This is not a footnote[^1\], but it also doesn't warn.
18+
LL +
19+
LL + This is not a `footnote[^1]`, but it also doesn't warn.
20+
LL +
21+
LL + This is a footnote[^2].
22+
LL +
23+
LL + [^2]: hello world
24+
LL +
25+
LL +
26+
LL + [^1]: <!-- description -->"#
1427
|
1528

1629
error: aborting due to 1 previous error

0 commit comments

Comments
 (0)