Skip to content

Commit 0d84f00

Browse files
committed
Auto merge of #12635 - Alexendoo:doc-check-attributes, r=Jarcho
Use `check_attributes` in doc lints Ensures we catch all the places that doc comments could occur, found one that we were currently missing - docs on `extern` items changelog: none
2 parents 6b1c828 + d4a8f61 commit 0d84f00

5 files changed

Lines changed: 84 additions & 90 deletions

File tree

‎clippy_lints/src/doc/missing_headers.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use super::{DocHeaders, MISSING_ERRORS_DOC, MISSING_PANICS_DOC, MISSING_SAFETY_D
1111
pubfncheck(
1212
cx:&LateContext<'_>,
1313
owner_id:OwnerId,
14-
sig:&FnSig<'_>,
14+
sig:FnSig<'_>,
1515
headers:DocHeaders,
1616
body_id:Option<BodyId>,
1717
panic_span:Option<Span>,

‎clippy_lints/src/doc/mod.rs‎

Lines changed: 61 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,16 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
33
use clippy_utils::macros::{is_panic, root_macro_call_first_node};
44
use clippy_utils::ty::is_type_diagnostic_item;
55
use clippy_utils::visitors::Visitable;
6-
use clippy_utils::{is_entrypoint_fn, method_chain_args};
6+
use clippy_utils::{is_entrypoint_fn,is_trait_impl_item,method_chain_args};
77
use pulldown_cmark::Event::{
88
Code,End,FootnoteReference,HardBreak,Html,Rule,SoftBreak,Start,TaskListMarker,Text,
99
};
1010
use pulldown_cmark::Tag::{BlockQuote,CodeBlock,Heading,Item,Link,Paragraph};
1111
use pulldown_cmark::{BrokenLink,CodeBlockKind,CowStr,Options};
1212
use rustc_ast::ast::Attribute;
1313
use rustc_data_structures::fx::FxHashSet;
14-
use rustc_hir as hir;
1514
use rustc_hir::intravisit::{self,Visitor};
16-
use rustc_hir::{AnonConst,Expr};
15+
use rustc_hir::{AnonConst,Expr,ImplItemKind,ItemKind,Node,TraitItemKind,Unsafety};
1716
use rustc_lint::{LateContext,LateLintPass,LintContext};
1817
use rustc_middle::hir::nested_filter;
1918
use rustc_middle::lint::in_external_macro;
@@ -366,15 +365,13 @@ declare_clippy_lint! {
366365
#[derive(Clone)]
367366
pubstructDocumentation{
368367
valid_idents:FxHashSet<String>,
369-
in_trait_impl:bool,
370368
check_private_items:bool,
371369
}
372370

373371
implDocumentation{
374372
pubfnnew(valid_idents:&[String],check_private_items:bool) -> Self{
375373
Self{
376374
valid_idents: valid_idents.iter().cloned().collect(),
377-
in_trait_impl:false,
378375
check_private_items,
379376
}
380377
}
@@ -394,36 +391,72 @@ impl_lint_pass!(Documentation => [
394391
]);
395392

396393
impl<'tcx>LateLintPass<'tcx>forDocumentation{
397-
fncheck_crate(&mutself,cx:&LateContext<'tcx>){
398-
let attrs = cx.tcx.hir().attrs(hir::CRATE_HIR_ID);
399-
check_attrs(cx,&self.valid_idents, attrs);
400-
}
401-
402-
fncheck_variant(&mutself,cx:&LateContext<'tcx>,variant:&'tcx hir::Variant<'tcx>){
403-
let attrs = cx.tcx.hir().attrs(variant.hir_id);
404-
check_attrs(cx,&self.valid_idents, attrs);
405-
}
406-
407-
fncheck_field_def(&mutself,cx:&LateContext<'tcx>,variant:&'tcx hir::FieldDef<'tcx>){
408-
let attrs = cx.tcx.hir().attrs(variant.hir_id);
409-
check_attrs(cx,&self.valid_idents, attrs);
410-
}
411-
412-
fncheck_item(&mutself,cx:&LateContext<'tcx>,item:&'tcx hir::Item<'_>){
413-
let attrs = cx.tcx.hir().attrs(item.hir_id());
394+
fncheck_attributes(&mutself,cx:&LateContext<'tcx>,attrs:&'tcx[Attribute]){
414395
letSome(headers) = check_attrs(cx,&self.valid_idents, attrs)else{
415396
return;
416397
};
417398

418-
match item.kind{
419-
hir::ItemKind::Fn(ref sig, _, body_id) => {
420-
if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)){
399+
match cx.tcx.hir_node(cx.last_node_with_lint_attrs){
400+
Node::Item(item) => match item.kind{
401+
ItemKind::Fn(sig, _, body_id) => {
402+
if !(is_entrypoint_fn(cx, item.owner_id.to_def_id()) || in_external_macro(cx.tcx.sess, item.span)){
403+
let body = cx.tcx.hir().body(body_id);
404+
405+
let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value);
406+
missing_headers::check(
407+
cx,
408+
item.owner_id,
409+
sig,
410+
headers,
411+
Some(body_id),
412+
panic_span,
413+
self.check_private_items,
414+
);
415+
}
416+
},
417+
ItemKind::Trait(_, unsafety, ..) => match(headers.safety, unsafety){
418+
(false,Unsafety::Unsafe) => span_lint(
419+
cx,
420+
MISSING_SAFETY_DOC,
421+
cx.tcx.def_span(item.owner_id),
422+
"docs for unsafe trait missing `# Safety` section",
423+
),
424+
(true,Unsafety::Normal) => span_lint(
425+
cx,
426+
UNNECESSARY_SAFETY_DOC,
427+
cx.tcx.def_span(item.owner_id),
428+
"docs for safe trait have unnecessary `# Safety` section",
429+
),
430+
_ => (),
431+
},
432+
_ => (),
433+
},
434+
Node::TraitItem(trait_item) => {
435+
ifletTraitItemKind::Fn(sig, ..) = trait_item.kind
436+
&& !in_external_macro(cx.tcx.sess, trait_item.span)
437+
{
438+
missing_headers::check(
439+
cx,
440+
trait_item.owner_id,
441+
sig,
442+
headers,
443+
None,
444+
None,
445+
self.check_private_items,
446+
);
447+
}
448+
},
449+
Node::ImplItem(impl_item) => {
450+
ifletImplItemKind::Fn(sig, body_id) = impl_item.kind
451+
&& !in_external_macro(cx.tcx.sess, impl_item.span)
452+
&& !is_trait_impl_item(cx, impl_item.hir_id())
453+
{
421454
let body = cx.tcx.hir().body(body_id);
422455

423-
let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value);
456+
let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(impl_item.owner_id), body.value);
424457
missing_headers::check(
425458
cx,
426-
item.owner_id,
459+
impl_item.owner_id,
427460
sig,
428461
headers,
429462
Some(body_id),
@@ -432,67 +465,7 @@ impl<'tcx> LateLintPass<'tcx> for Documentation {
432465
);
433466
}
434467
},
435-
hir::ItemKind::Impl(impl_) => {
436-
self.in_trait_impl = impl_.of_trait.is_some();
437-
},
438-
hir::ItemKind::Trait(_, unsafety, ..) => match(headers.safety, unsafety){
439-
(false, hir::Unsafety::Unsafe) => span_lint(
440-
cx,
441-
MISSING_SAFETY_DOC,
442-
cx.tcx.def_span(item.owner_id),
443-
"docs for unsafe trait missing `# Safety` section",
444-
),
445-
(true, hir::Unsafety::Normal) => span_lint(
446-
cx,
447-
UNNECESSARY_SAFETY_DOC,
448-
cx.tcx.def_span(item.owner_id),
449-
"docs for safe trait have unnecessary `# Safety` section",
450-
),
451-
_ => (),
452-
},
453-
_ => (),
454-
}
455-
}
456-
457-
fncheck_item_post(&mutself,_cx:&LateContext<'tcx>,item:&'tcx hir::Item<'_>){
458-
iflet hir::ItemKind::Impl{ .. } = item.kind{
459-
self.in_trait_impl = false;
460-
}
461-
}
462-
463-
fncheck_trait_item(&mutself,cx:&LateContext<'tcx>,item:&'tcx hir::TraitItem<'_>){
464-
let attrs = cx.tcx.hir().attrs(item.hir_id());
465-
letSome(headers) = check_attrs(cx,&self.valid_idents, attrs)else{
466-
return;
467-
};
468-
iflet hir::TraitItemKind::Fn(ref sig, ..) = item.kind{
469-
if !in_external_macro(cx.tcx.sess, item.span){
470-
missing_headers::check(cx, item.owner_id, sig, headers,None,None,self.check_private_items);
471-
}
472-
}
473-
}
474-
475-
fncheck_impl_item(&mutself,cx:&LateContext<'tcx>,item:&'tcx hir::ImplItem<'_>){
476-
let attrs = cx.tcx.hir().attrs(item.hir_id());
477-
letSome(headers) = check_attrs(cx,&self.valid_idents, attrs)else{
478-
return;
479-
};
480-
ifself.in_trait_impl || in_external_macro(cx.tcx.sess, item.span){
481-
return;
482-
}
483-
iflet hir::ImplItemKind::Fn(ref sig, body_id) = item.kind{
484-
let body = cx.tcx.hir().body(body_id);
485-
486-
let panic_span = FindPanicUnwrap::find_span(cx, cx.tcx.typeck(item.owner_id), body.value);
487-
missing_headers::check(
488-
cx,
489-
item.owner_id,
490-
sig,
491-
headers,
492-
Some(body_id),
493-
panic_span,
494-
self.check_private_items,
495-
);
468+
_ => {},
496469
}
497470
}
498471
}

‎tests/ui/doc/doc-fixable.fixed‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,8 @@ fn parenthesized_word() {}
235235
/// OSes
236236
/// UXes
237237
fn plural_acronym_test() {}
238+
239+
extern {
240+
/// `foo()`
241+
fn in_extern();
242+
}

‎tests/ui/doc/doc-fixable.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,8 @@ fn parenthesized_word() {}
235235
/// OSes
236236
/// UXes
237237
fnplural_acronym_test(){}
238+
239+
extern{
240+
/// foo()
241+
fnin_extern();
242+
}

‎tests/ui/doc/doc-fixable.stderr‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,5 +352,16 @@ help: try
352352
LL | /// `ABes`
353353
| ~~~~~~
354354

355-
error: aborting due to 32 previous errors
355+
error: item in documentation is missing backticks
356+
--> tests/ui/doc/doc-fixable.rs:240:9
357+
|
358+
LL | /// foo()
359+
| ^^^^^
360+
|
361+
help: try
362+
|
363+
LL | /// `foo()`
364+
| ~~~~~~~
365+
366+
error: aborting due to 33 previous errors
356367

0 commit comments

Comments
 (0)