Skip to content

Commit 4d26c5c

Browse files
committed
Auto merge of #7904 - Serial-ATA:improve-doc-suggestion, r=xFrednet
Add suggestion to missing backticks error changelog: Add a machine applicable suggestion for the [`doc_markdown`] missing backticks lint closes: #7737
2 parents c68af43 + 3732d11 commit 4d26c5c

File tree

8 files changed

+437
-238
lines changed

8 files changed

+437
-238
lines changed

clippy_lints/src/doc.rs

+15-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use clippy_utils::attrs::is_doc_hidden;
2-
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_note};
3-
use clippy_utils::source::first_line_of_span;
2+
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_note, span_lint_and_sugg};
3+
use clippy_utils::source::{first_line_of_span, snippet_with_applicability};
44
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
55
use clippy_utils::{is_entrypoint_fn, is_expn_of, match_panic_def_id, method_chain_args, return_ty};
66
use if_chain::if_chain;
@@ -10,7 +10,7 @@ use rustc_ast::token::CommentKind;
1010
use rustc_data_structures::fx::FxHashSet;
1111
use rustc_data_structures::sync::Lrc;
1212
use rustc_errors::emitter::EmitterWriter;
13-
use rustc_errors::Handler;
13+
use rustc_errors::{Applicability, Handler};
1414
use rustc_hir as hir;
1515
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
1616
use rustc_hir::{AnonConst, Expr, ExprKind, QPath};
@@ -48,7 +48,7 @@ declare_clippy_lint! {
4848
/// content are not linted.
4949
///
5050
/// In addition, when writing documentation comments, including `[]` brackets
51-
/// inside a link text would trip the parser. Therfore, documenting link with
51+
/// inside a link text would trip the parser. Therefore, documenting link with
5252
/// `[`SmallVec<[T; INLINE_CAPACITY]>`]` and then [`SmallVec<[T; INLINE_CAPACITY]>`]: SmallVec
5353
/// would fail.
5454
///
@@ -755,17 +755,22 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
755755
}
756756
}
757757

758-
// We assume that mixed-case words are not meant to be put inside bacticks. (Issue #2343)
758+
// We assume that mixed-case words are not meant to be put inside backticks. (Issue #2343)
759759
if has_underscore(word) && has_hyphen(word) {
760760
return;
761761
}
762762

763763
if has_underscore(word) || word.contains("::") || is_camel_case(word) {
764-
span_lint(
764+
let mut applicability = Applicability::MachineApplicable;
765+
766+
span_lint_and_sugg(
765767
cx,
766768
DOC_MARKDOWN,
767769
span,
768-
&format!("you should put `{}` between ticks in the documentation", word),
770+
"item in documentation is missing backticks",
771+
"try",
772+
format!("`{}`", snippet_with_applicability(cx, span, "..", &mut applicability)),
773+
applicability,
769774
);
770775
}
771776
}
@@ -804,9 +809,9 @@ impl<'a, 'tcx> Visitor<'tcx> for FindPanicUnwrap<'a, 'tcx> {
804809

805810
// check for `unwrap`
806811
if let Some(arglists) = method_chain_args(expr, &["unwrap"]) {
807-
let reciever_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
808-
if is_type_diagnostic_item(self.cx, reciever_ty, sym::Option)
809-
|| is_type_diagnostic_item(self.cx, reciever_ty, sym::Result)
812+
let receiver_ty = self.typeck_results.expr_ty(&arglists[0][0]).peel_refs();
813+
if is_type_diagnostic_item(self.cx, receiver_ty, sym::Option)
814+
|| is_type_diagnostic_item(self.cx, receiver_ty, sym::Result)
810815
{
811816
self.panic_span = Some(expr.span);
812817
}

tests/ui/doc/doc-fixable.fixed

+215
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
// run-rustfix
2+
//! This file tests for the `DOC_MARKDOWN` lint.
3+
4+
#![allow(dead_code, incomplete_features)]
5+
#![warn(clippy::doc_markdown)]
6+
#![feature(custom_inner_attributes, generic_const_exprs, const_option)]
7+
#![rustfmt::skip]
8+
9+
/// The `foo_bar` function does _nothing_. See also `foo::bar`. (note the dot there)
10+
/// Markdown is _weird_. I mean _really weird_. This \_ is ok. So is `_`. But not `Foo::some_fun`
11+
/// which should be reported only once despite being __doubly bad__.
12+
/// Here be `::a::global:path`, and _`::another::global::path`_. :: is not a path though.
13+
/// Import an item from `::awesome::global::blob::` (Intended postfix)
14+
/// These are the options for `::Cat`: (Intended trailing single colon, shouldn't be linted)
15+
/// That's not code ~`NotInCodeBlock`~.
16+
/// `be_sure_we_got_to_the_end_of_it`
17+
fn foo_bar() {
18+
}
19+
20+
/// That one tests multiline ticks.
21+
/// ```rust
22+
/// foo_bar FOO_BAR
23+
/// _foo bar_
24+
/// ```
25+
///
26+
/// ~~~rust
27+
/// foo_bar FOO_BAR
28+
/// _foo bar_
29+
/// ~~~
30+
/// `be_sure_we_got_to_the_end_of_it`
31+
fn multiline_codeblock() {
32+
}
33+
34+
/// This _is a test for
35+
/// multiline
36+
/// emphasis_.
37+
/// `be_sure_we_got_to_the_end_of_it`
38+
fn test_emphasis() {
39+
}
40+
41+
/// This tests units. See also #835.
42+
/// kiB MiB GiB TiB PiB EiB
43+
/// kib Mib Gib Tib Pib Eib
44+
/// kB MB GB TB PB EB
45+
/// kb Mb Gb Tb Pb Eb
46+
/// 32kiB 32MiB 32GiB 32TiB 32PiB 32EiB
47+
/// 32kib 32Mib 32Gib 32Tib 32Pib 32Eib
48+
/// 32kB 32MB 32GB 32TB 32PB 32EB
49+
/// 32kb 32Mb 32Gb 32Tb 32Pb 32Eb
50+
/// NaN
51+
/// `be_sure_we_got_to_the_end_of_it`
52+
fn test_units() {
53+
}
54+
55+
/// This tests allowed identifiers.
56+
/// KiB MiB GiB TiB PiB EiB
57+
/// DirectX
58+
/// ECMAScript
59+
/// GPLv2 GPLv3
60+
/// GitHub GitLab
61+
/// IPv4 IPv6
62+
/// ClojureScript CoffeeScript JavaScript PureScript TypeScript
63+
/// NaN NaNs
64+
/// OAuth GraphQL
65+
/// OCaml
66+
/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS
67+
/// WebGL
68+
/// TensorFlow
69+
/// TrueType
70+
/// iOS macOS FreeBSD
71+
/// TeX LaTeX BibTeX BibLaTeX
72+
/// MinGW
73+
/// CamelCase (see also #2395)
74+
/// `be_sure_we_got_to_the_end_of_it`
75+
fn test_allowed() {
76+
}
77+
78+
/// This test has [a `link_with_underscores`][chunked-example] inside it. See #823.
79+
/// See also [the issue tracker](https://github.com/rust-lang/rust-clippy/search?q=clippy::doc_markdown&type=Issues)
80+
/// on GitHub (which is a camel-cased word, but is OK). And here is another [inline link][inline_link].
81+
/// It can also be [`inline_link2`].
82+
///
83+
/// [chunked-example]: https://en.wikipedia.org/wiki/Chunked_transfer_encoding#Example
84+
/// [inline_link]: https://foobar
85+
/// [inline_link2]: https://foobar
86+
/// The `main` function is the entry point of the program. Here it only calls the `foo_bar` and
87+
/// `multiline_ticks` functions.
88+
///
89+
/// expression of the type `_ <bit_op> m <cmp_op> c` (where `<bit_op>`
90+
/// is one of {`&`, '|'} and `<cmp_op>` is one of {`!=`, `>=`, `>` ,
91+
/// `be_sure_we_got_to_the_end_of_it`
92+
fn main() {
93+
foo_bar();
94+
multiline_codeblock();
95+
test_emphasis();
96+
test_units();
97+
}
98+
99+
/// ## `CamelCaseThing`
100+
/// Talks about `CamelCaseThing`. Titles should be ignored; see issue #897.
101+
///
102+
/// # `CamelCaseThing`
103+
///
104+
/// Not a title #897 `CamelCaseThing`
105+
/// `be_sure_we_got_to_the_end_of_it`
106+
fn issue897() {
107+
}
108+
109+
/// I am confused by brackets? (`x_y`)
110+
/// I am confused by brackets? (foo `x_y`)
111+
/// I am confused by brackets? (`x_y` foo)
112+
/// `be_sure_we_got_to_the_end_of_it`
113+
fn issue900() {
114+
}
115+
116+
/// Diesel queries also have a similar problem to [Iterator][iterator], where
117+
/// /// More talking
118+
/// returning them from a function requires exposing the implementation of that
119+
/// function. The [`helper_types`][helper_types] module exists to help with this,
120+
/// but you might want to hide the return type or have it conditionally change.
121+
/// Boxing can achieve both.
122+
///
123+
/// [iterator]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html
124+
/// [helper_types]: ../helper_types/index.html
125+
/// `be_sure_we_got_to_the_end_of_it`
126+
fn issue883() {
127+
}
128+
129+
/// `foo_bar
130+
/// baz_quz`
131+
/// [foo
132+
/// bar](https://doc.rust-lang.org/stable/std/iter/trait.IteratorFooBar.html)
133+
fn multiline() {
134+
}
135+
136+
/** E.g., serialization of an empty list: `FooBar`
137+
```
138+
That's in a code block: `PackedNode`
139+
```
140+
141+
And `BarQuz` too.
142+
`be_sure_we_got_to_the_end_of_it`
143+
*/
144+
fn issue1073() {
145+
}
146+
147+
/** E.g., serialization of an empty list: `FooBar`
148+
```
149+
That's in a code block: PackedNode
150+
```
151+
152+
And `BarQuz` too.
153+
`be_sure_we_got_to_the_end_of_it`
154+
*/
155+
fn issue1073_alt() {
156+
}
157+
158+
/// Tests more than three quotes:
159+
/// ````
160+
/// DoNotWarn
161+
/// ```
162+
/// StillDont
163+
/// ````
164+
/// `be_sure_we_got_to_the_end_of_it`
165+
fn four_quotes() {
166+
}
167+
168+
#[cfg_attr(feature = "a", doc = " ```")]
169+
#[cfg_attr(not(feature = "a"), doc = " ```ignore")]
170+
/// fn main() {
171+
/// let s = "localhost:10000".to_string();
172+
/// println!("{}", s);
173+
/// }
174+
/// ```
175+
fn issue_1469() {}
176+
177+
/**
178+
* This is a doc comment that should not be a list
179+
*This would also be an error under a strict common mark interpretation
180+
*/
181+
fn issue_1920() {}
182+
183+
/// An iterator over `mycrate::Collection`'s values.
184+
/// It should not lint a `'static` lifetime in ticks.
185+
fn issue_2210() {}
186+
187+
/// This should not cause the lint to trigger:
188+
/// #REQ-data-family.lint_partof_exists
189+
fn issue_2343() {}
190+
191+
/// This should not cause an ICE:
192+
/// __|_ _|__||_|
193+
fn pulldown_cmark_crash() {}
194+
195+
/// This should not lint
196+
/// (regression test for #7758)
197+
/// [plain text][path::to::item]
198+
fn intra_doc_link() {}
199+
200+
// issue #7033 - generic_const_exprs ICE
201+
struct S<T, const N: usize>
202+
where [(); N.checked_next_power_of_two().unwrap()]: {
203+
arr: [T; N.checked_next_power_of_two().unwrap()],
204+
n: usize,
205+
}
206+
207+
impl<T: Copy + Default, const N: usize> S<T, N>
208+
where [(); N.checked_next_power_of_two().unwrap()]: {
209+
fn new() -> Self {
210+
Self {
211+
arr: [T::default(); N.checked_next_power_of_two().unwrap()],
212+
n: 0,
213+
}
214+
}
215+
}

tests/ui/doc/doc.rs renamed to tests/ui/doc/doc-fixable.rs

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// run-rustfix
12
//! This file tests for the `DOC_MARKDOWN` lint.
23
34
#![allow(dead_code, incomplete_features)]
@@ -164,12 +165,6 @@ fn issue1073_alt() {
164165
fn four_quotes() {
165166
}
166167

167-
/// See [NIST SP 800-56A, revision 2].
168-
///
169-
/// [NIST SP 800-56A, revision 2]:
170-
/// https://github.com/rust-lang/rust-clippy/issues/902#issuecomment-261919419
171-
fn issue_902_comment() {}
172-
173168
#[cfg_attr(feature = "a", doc = " ```")]
174169
#[cfg_attr(not(feature = "a"), doc = " ```ignore")]
175170
/// fn main() {
@@ -185,14 +180,6 @@ fn issue_1469() {}
185180
*/
186181
fn issue_1920() {}
187182

188-
/// Ok: <http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels>
189-
///
190-
/// Not ok: http://www.unicode.org
191-
/// Not ok: https://www.unicode.org
192-
/// Not ok: http://www.unicode.org/
193-
/// Not ok: http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
194-
fn issue_1832() {}
195-
196183
/// An iterator over mycrate::Collection's values.
197184
/// It should not lint a `'static` lifetime in ticks.
198185
fn issue_2210() {}

0 commit comments

Comments
 (0)