@@ -4,9 +4,10 @@ use clippy_utils::diagnostics::span_lint_and_help;
44use clippy_utils:: source:: walk_span_to_context;
55use clippy_utils:: visitors:: { for_each_expr_with_closures, Descend } ;
66use clippy_utils:: { get_parent_node, is_lint_allowed} ;
7+ use hir:: OwnerId ;
78use rustc_data_structures:: sync:: Lrc ;
89use rustc_hir as hir;
9- use rustc_hir:: { Block , BlockCheckMode , HirId , ItemKind , Node , OwnerNode , UnsafeSource } ;
10+ use rustc_hir:: { Block , BlockCheckMode , HirId , ItemKind , Node , UnsafeSource } ;
1011use rustc_lexer:: { tokenize, TokenKind } ;
1112use rustc_lint:: { LateContext , LateLintPass , LintContext } ;
1213use rustc_middle:: lint:: in_external_macro;
@@ -524,25 +525,34 @@ fn item_has_safety_comment(cx: &LateContext<'_>, hir_id: HirId, owner: hir::Owne
524525 has_safety_comment => return has_safety_comment,
525526 }
526527
527- if owner. span ( ) . ctxt ( ) != SyntaxContext :: root ( ) {
528+ if owner. span ( ) . from_expansion ( ) {
528529 return HasSafetyComment :: No ;
529530 }
530531 if let Some ( parent_node) = get_parent_node ( cx. tcx , hir_id) {
531532 let comment_start = match parent_node {
532- Node :: Crate ( parent_mod) => {
533- comment_start_pos_in_parent_context ( cx, parent_mod. item_ids , parent_mod. spans . inner_span , owner)
534- } ,
533+ Node :: Crate ( parent_mod) => comment_start_pos (
534+ cx,
535+ parent_mod. item_ids . iter ( ) . map ( |id| id. owner_id ) ,
536+ parent_mod. spans . inner_span ,
537+ owner. def_id ( ) ,
538+ ) ,
535539 Node :: Item ( parent_item) => {
536540 match parent_item. kind {
537- ItemKind :: Mod ( parent_mod) => {
538- comment_start_pos_in_parent_context ( cx, parent_mod. item_ids , parent_item. span , owner)
539- } ,
541+ ItemKind :: Mod ( parent_mod) => comment_start_pos (
542+ cx,
543+ parent_mod. item_ids . iter ( ) . map ( |id| id. owner_id ) ,
544+ parent_item. span ,
545+ owner. def_id ( ) ,
546+ ) ,
540547 ItemKind :: Trait ( _, _, _, _, refs) => {
541- comment_start_pos_in_parent_context ( cx, refs, parent_item. span , owner)
542- } ,
543- ItemKind :: Impl ( hir:: Impl { items, .. } ) => {
544- comment_start_pos_in_parent_context ( cx, items, parent_item. span , owner)
548+ comment_start_pos ( cx, refs. iter ( ) . map ( |r| r. id . owner_id ) , parent_item. span , owner. def_id ( ) )
545549 } ,
550+ ItemKind :: Impl ( hir:: Impl { items, .. } ) => comment_start_pos (
551+ cx,
552+ items. iter ( ) . map ( |r| r. id . owner_id ) ,
553+ parent_item. span ,
554+ owner. def_id ( ) ,
555+ ) ,
546556 // Doesn't support impls in this position. Pretend a comment was found.
547557 _ => return HasSafetyComment :: Maybe ,
548558 }
@@ -627,71 +637,19 @@ fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> H
627637 HasSafetyComment :: Maybe
628638}
629639
630- trait CheckableItemId {
631- fn owner_id ( & self ) -> hir:: OwnerId ;
632- }
633-
634- impl CheckableItemId for hir:: ItemId {
635- fn owner_id ( & self ) -> hir:: OwnerId {
636- self . owner_id
637- }
638- }
639- impl CheckableItemId for hir:: ImplItemRef {
640- fn owner_id ( & self ) -> hir:: OwnerId {
641- self . id . owner_id
642- }
643- }
644- impl CheckableItemId for hir:: TraitItemRef {
645- fn owner_id ( & self ) -> hir:: OwnerId {
646- self . id . owner_id
647- }
648- }
649-
650640/// Search and return the starting [`BytePos`] of the comment above an 'item' in its context.
651- fn comment_start_pos_in_parent_context < T : CheckableItemId > (
641+ fn comment_start_pos < I : Iterator < Item = OwnerId > > (
652642 cx : & LateContext < ' _ > ,
653- ids : & [ T ] ,
643+ siblings : I ,
654644 search_span : Span ,
655- owner : OwnerNode < ' _ > ,
645+ owner_id : OwnerId ,
656646) -> Option < BytePos > {
657- let map = cx. tcx . hir ( ) ;
658- ids. iter ( ) . enumerate ( ) . find_map ( |( idx, id) | {
659- if id. owner_id ( ) == owner. def_id ( ) {
660- if idx == 0 {
661- // mod A { /* comment */ unsafe impl T {} ... }
662- // ^------------------------------------------^ returns the start of this span
663- // ^---------------------^ finally checks comments in this range
664- walk_span_to_context ( search_span, SyntaxContext :: root ( ) ) . map ( Span :: lo)
665- } else {
666- // some_item /* comment */ unsafe impl T {}
667- // ^-------^ returns the end of this span
668- // ^---------------^ finally checks comments in this range
669- match owner {
670- OwnerNode :: Item ( _) => {
671- let prev_item = map. item ( hir:: ItemId {
672- owner_id : ids[ idx - 1 ] . owner_id ( ) ,
673- } ) ;
674- walk_span_to_context ( prev_item. span , SyntaxContext :: root ( ) ) . map ( Span :: lo)
675- } ,
676- OwnerNode :: ImplItem ( _) => {
677- let prev_impl_item = map. impl_item ( hir:: ImplItemId {
678- owner_id : ids[ idx - 1 ] . owner_id ( ) ,
679- } ) ;
680- walk_span_to_context ( prev_impl_item. span , SyntaxContext :: root ( ) ) . map ( Span :: lo)
681- } ,
682- OwnerNode :: TraitItem ( _) => {
683- let prev_trait_item = map. trait_item ( hir:: TraitItemId {
684- owner_id : ids[ idx - 1 ] . owner_id ( ) ,
685- } ) ;
686- walk_span_to_context ( prev_trait_item. span , SyntaxContext :: root ( ) ) . map ( Span :: lo)
687- } ,
688- _ => None ,
689- }
690- }
691- } else {
692- None
693- }
694- } )
647+ if let Some ( id) = siblings. take_while ( |id| * id != owner_id) . last ( ) {
648+ let prev_sibling_span = cx. tcx . hir ( ) . span ( id. into ( ) ) ;
649+ walk_span_to_context ( prev_sibling_span, SyntaxContext :: root ( ) ) . map ( Span :: lo)
650+ } else {
651+ walk_span_to_context ( search_span, SyntaxContext :: root ( ) ) . map ( Span :: lo)
652+ }
695653}
696654
697655fn span_from_macro_expansion_has_safety_comment ( cx : & LateContext < ' _ > , span : Span ) -> HasSafetyComment {
@@ -730,13 +688,8 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span
730688
731689fn get_body_search_span ( cx : & LateContext < ' _ > ) -> Option < Span > {
732690 let body = cx. enclosing_body ?;
733- let map = cx. tcx . hir ( ) ;
734- let mut span = map. body ( body) . value . span ;
735- let mut is_const_or_static = false ;
736- for ( _, parent_node) in map. parent_iter ( body. hir_id ) {
691+ for ( _, parent_node) in cx. tcx . hir ( ) . parent_iter ( body. hir_id ) {
737692 match parent_node {
738- Node :: Expr ( e) => span = e. span ,
739- Node :: Block ( _) | Node :: Arm ( _) | Node :: Stmt ( _) | Node :: Local ( _) => ( ) ,
740693 Node :: Item ( hir:: Item {
741694 kind : hir:: ItemKind :: Const ( ..) | ItemKind :: Static ( ..) ,
742695 ..
@@ -748,22 +701,13 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
748701 | Node :: TraitItem ( hir:: TraitItem {
749702 kind : hir:: TraitItemKind :: Const ( ..) ,
750703 ..
751- } ) => is_const_or_static = true ,
752- // Parent is a `mod xxx { .. }``
753- Node :: Item ( item) => {
754- match item. kind {
755- ItemKind :: Mod ( _) | ItemKind :: Trait ( ..) | ItemKind :: Impl ( ..) => span = item. span ,
756- _ => ( ) ,
757- }
758- break ;
759- } ,
760- Node :: Crate ( mod_) if is_const_or_static => {
761- span = mod_. spans . inner_span ;
762- } ,
763- _ => break ,
704+ } ) => { } ,
705+ Node :: Item ( item) => return Some ( item. span ) ,
706+ Node :: Crate ( mod_) => return Some ( mod_. spans . inner_span ) ,
707+ _ => { } ,
764708 }
765709 }
766- Some ( span )
710+ None
767711}
768712
769713fn span_has_safety_comment ( cx : & LateContext < ' _ > , span : Span ) -> bool {
0 commit comments