@@ -3,17 +3,16 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
33use clippy_utils:: macros:: { is_panic, root_macro_call_first_node} ;
44use clippy_utils:: ty:: is_type_diagnostic_item;
55use 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} ;
77use pulldown_cmark:: Event :: {
88 Code , End , FootnoteReference , HardBreak , Html , Rule , SoftBreak , Start , TaskListMarker , Text ,
99} ;
1010use pulldown_cmark:: Tag :: { BlockQuote , CodeBlock , Heading , Item , Link , Paragraph } ;
1111use pulldown_cmark:: { BrokenLink , CodeBlockKind , CowStr , Options } ;
1212use rustc_ast:: ast:: Attribute ;
1313use rustc_data_structures:: fx:: FxHashSet ;
14- use rustc_hir as hir;
1514use rustc_hir:: intravisit:: { self , Visitor } ;
16- use rustc_hir:: { AnonConst , Expr } ;
15+ use rustc_hir:: { AnonConst , Expr , ImplItemKind , ItemKind , Node , TraitItemKind , Unsafety } ;
1716use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
1817use rustc_middle:: hir:: nested_filter;
1918use rustc_middle:: lint:: in_external_macro;
@@ -366,15 +365,13 @@ declare_clippy_lint! {
366365#[ derive( Clone ) ]
367366pub struct Documentation {
368367 valid_idents : FxHashSet < String > ,
369- in_trait_impl : bool ,
370368 check_private_items : bool ,
371369}
372370
373371impl Documentation {
374372 pub fn new ( 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
396393impl < ' tcx > LateLintPass < ' tcx > for Documentation {
397- fn check_crate ( & mut self , 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- fn check_variant ( & mut self , 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- fn check_field_def ( & mut self , 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- fn check_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx hir:: Item < ' _ > ) {
413- let attrs = cx. tcx . hir ( ) . attrs ( item. hir_id ( ) ) ;
394+ fn check_attributes ( & mut self , cx : & LateContext < ' tcx > , attrs : & ' tcx [ Attribute ] ) {
414395 let Some ( 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+ if let TraitItemKind :: 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+ if let ImplItemKind :: 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- fn check_item_post ( & mut self , _cx : & LateContext < ' tcx > , item : & ' tcx hir:: Item < ' _ > ) {
458- if let hir:: ItemKind :: Impl { .. } = item. kind {
459- self . in_trait_impl = false ;
460- }
461- }
462-
463- fn check_trait_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx hir:: TraitItem < ' _ > ) {
464- let attrs = cx. tcx . hir ( ) . attrs ( item. hir_id ( ) ) ;
465- let Some ( headers) = check_attrs ( cx, & self . valid_idents , attrs) else {
466- return ;
467- } ;
468- if let 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- fn check_impl_item ( & mut self , cx : & LateContext < ' tcx > , item : & ' tcx hir:: ImplItem < ' _ > ) {
476- let attrs = cx. tcx . hir ( ) . attrs ( item. hir_id ( ) ) ;
477- let Some ( headers) = check_attrs ( cx, & self . valid_idents , attrs) else {
478- return ;
479- } ;
480- if self . in_trait_impl || in_external_macro ( cx. tcx . sess , item. span ) {
481- return ;
482- }
483- if let 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}
0 commit comments