Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move suspicious_doc_comments to doc pass #11798

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion clippy_lints/src/declared_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::doc::MISSING_PANICS_DOC_INFO,
crate::doc::MISSING_SAFETY_DOC_INFO,
crate::doc::NEEDLESS_DOCTEST_MAIN_INFO,
crate::doc::SUSPICIOUS_DOC_COMMENTS_INFO,
crate::doc::UNNECESSARY_SAFETY_DOC_INFO,
crate::double_parens::DOUBLE_PARENS_INFO,
crate::drop_forget_ref::DROP_NON_DROP_INFO,
Expand Down Expand Up @@ -626,7 +627,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::strings::STR_TO_STRING_INFO,
crate::strings::TRIM_SPLIT_WHITESPACE_INFO,
crate::strlen_on_c_strings::STRLEN_ON_C_STRINGS_INFO,
crate::suspicious_doc_comments::SUSPICIOUS_DOC_COMMENTS_INFO,
crate::suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS_INFO,
crate::suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL_INFO,
crate::suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL_INFO,
Expand Down
89 changes: 89 additions & 0 deletions clippy_lints/src/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use pulldown_cmark::Event::{
use pulldown_cmark::Tag::{CodeBlock, Heading, Item, Link, Paragraph};
use pulldown_cmark::{BrokenLink, CodeBlockKind, CowStr, Options};
use rustc_ast::ast::{Async, Attribute, Fn, FnRetTy, ItemKind};
use rustc_ast::token::CommentKind;
use rustc_ast::{AttrKind, AttrStyle};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
use rustc_errors::emitter::EmitterWriter;
Expand Down Expand Up @@ -260,6 +262,53 @@ declare_clippy_lint! {
"`pub fn` or `pub trait` with `# Safety` docs"
}

declare_clippy_lint! {
/// ### What it does
/// Detects the use of outer doc comments (`///`, `/**`) followed by a bang (`!`): `///!`
///
/// ### Why is this bad?
/// Triple-slash comments (known as "outer doc comments") apply to items that follow it.
/// An outer doc comment followed by a bang (i.e. `///!`) has no specific meaning.
///
/// The user most likely meant to write an inner doc comment (`//!`, `/*!`), which
/// applies to the parent item (i.e. the item that the comment is contained in,
/// usually a module or crate).
///
/// ### Known problems
/// Inner doc comments can only appear before items, so there are certain cases where the suggestion
/// made by this lint is not valid code. For example:
/// ```rs
/// fn foo() {}
/// ///!
/// fn bar() {}
/// ```
/// This lint detects the doc comment and suggests changing it to `//!`, but an inner doc comment
/// is not valid at that position.
///
/// ### Example
/// In this example, the doc comment is attached to the *function*, rather than the *module*.
/// ```no_run
/// pub mod util {
/// ///! This module contains utility functions.
///
/// pub fn dummy() {}
/// }
/// ```
///
/// Use instead:
/// ```no_run
/// pub mod util {
/// //! This module contains utility functions.
///
/// pub fn dummy() {}
/// }
/// ```
#[clippy::version = "1.70.0"]
pub SUSPICIOUS_DOC_COMMENTS,
suspicious,
"suspicious usage of (outer) doc comments"
}

#[expect(clippy::module_name_repetitions)]
#[derive(Clone)]
pub struct DocMarkdown {
Expand All @@ -284,6 +333,7 @@ impl_lint_pass!(DocMarkdown => [
MISSING_PANICS_DOC,
NEEDLESS_DOCTEST_MAIN,
UNNECESSARY_SAFETY_DOC,
SUSPICIOUS_DOC_COMMENTS
]);

impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
Expand Down Expand Up @@ -478,6 +528,8 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
return None;
}

check_almost_inner_doc(cx, attrs);

let (fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
let mut doc = String::new();
for fragment in &fragments {
Expand Down Expand Up @@ -506,6 +558,43 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
))
}

/// Looks for `///!` and `/**!` comments, which were probably meant to be `//!` and `/*!`
fn check_almost_inner_doc(cx: &LateContext<'_>, attrs: &[Attribute]) {
let replacements: Vec<_> = 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();

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,
);
},
);
}
}

const RUST_CODE: &[&str] = &["rust", "no_run", "should_panic", "compile_fail"];

#[allow(clippy::too_many_lines)] // Only a big match statement
Expand Down
2 changes: 0 additions & 2 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,6 @@ mod slow_vector_initialization;
mod std_instead_of_core;
mod strings;
mod strlen_on_c_strings;
mod suspicious_doc_comments;
mod suspicious_operation_groupings;
mod suspicious_trait_impl;
mod suspicious_xor_used_as_pow;
Expand Down Expand Up @@ -1000,7 +999,6 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(|_| Box::new(lines_filter_map_ok::LinesFilterMapOk));
store.register_late_pass(|_| Box::new(tests_outside_test_module::TestsOutsideTestModule));
store.register_late_pass(|_| Box::new(manual_slice_size_calculation::ManualSliceSizeCalculation));
store.register_early_pass(|| Box::new(suspicious_doc_comments::SuspiciousDocComments));
store.register_early_pass(move || {
Box::new(excessive_nesting::ExcessiveNesting {
excessive_nesting_threshold,
Expand Down
92 changes: 0 additions & 92 deletions clippy_lints/src/suspicious_doc_comments.rs

This file was deleted.