diff options
Diffstat (limited to 'src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs')
-rw-r--r-- | src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs new file mode 100644 index 000000000..d7ad30efe --- /dev/null +++ b/src/tools/clippy/clippy_lints/src/doc/suspicious_doc_comments.rs @@ -0,0 +1,48 @@ +use clippy_utils::diagnostics::span_lint_and_then; +use rustc_ast::token::CommentKind; +use rustc_ast::{AttrKind, AttrStyle, Attribute}; +use rustc_errors::Applicability; +use rustc_lint::LateContext; +use rustc_span::Span; + +use super::SUSPICIOUS_DOC_COMMENTS; + +pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { + let replacements: Vec<_> = collect_doc_replacements(attrs); + + if let Some((&(lo_span, _), &(hi_span, _))) = replacements.first().zip(replacements.last()) { + span_lint_and_then( + cx, + SUSPICIOUS_DOC_COMMENTS, + lo_span.to(hi_span), + "this is an outer doc comment and does not apply to the parent module or crate", + |diag| { + diag.multipart_suggestion( + "use an inner doc comment to document the parent module or crate", + replacements, + Applicability::MaybeIncorrect, + ); + }, + ); + } +} + +fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { + attrs + .iter() + .filter_map(|attr| { + if let AttrKind::DocComment(com_kind, sym) = attr.kind + && let AttrStyle::Outer = attr.style + && let Some(com) = sym.as_str().strip_prefix('!') + { + let sugg = match com_kind { + CommentKind::Line => format!("//!{com}"), + CommentKind::Block => format!("/*!{com}*/"), + }; + Some((attr.span, sugg)) + } else { + None + } + }) + .collect() +} |