@@ -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;
@@ -263,59 +264,43 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
263264 // NB: This does not check undocumented unsafe block as they are handled
264265 // by `check_block` and `block_parents_have_safety_comment`
265266 fn check_trait_item ( & mut self , cx : & LateContext < ' _ > , trait_item : & hir:: TraitItem < ' _ > ) {
266- if in_external_macro ( cx. tcx . sess , trait_item. span )
267- || is_lint_allowed ( cx, UNNECESSARY_SAFETY_COMMENT , trait_item. hir_id ( ) )
268- {
269- return ;
270- }
271-
272- let hir:: TraitItemKind :: Const ( _, Some ( body_id) ) = trait_item. kind else {
267+ let hir:: TraitItemKind :: Const ( ..) = trait_item. kind else {
273268 return ;
274269 } ;
275- if body_is_unsafe_block ( cx, body_id) {
276- return ;
277- }
278-
279- if let HasSafetyComment :: Yes ( pos) = item_has_safety_comment ( cx, trait_item. hir_id ( ) , trait_item. into ( ) ) {
280- let ( span, help_span) = mk_spans ( cx, trait_item. span , pos) ;
281- span_lint_and_help (
282- cx,
283- UNNECESSARY_SAFETY_COMMENT ,
284- span,
285- "associated constant has unnecessary safety comment" ,
286- Some ( help_span) ,
287- "consider removing the safety comment" ,
288- ) ;
289- }
270+ lint_usc_on_associated_consts ( cx, trait_item, trait_item. hir_id ( ) ) ;
290271 }
291272
292273 // Check unnecessary unsafe comment above impl items.
293274 // NB: Same as [`check_trait_item`] above, this does not check undocumented unsafe block.
294275 fn check_impl_item ( & mut self , cx : & LateContext < ' _ > , impl_item : & hir:: ImplItem < ' _ > ) {
295- if in_external_macro ( cx. tcx . sess , impl_item. span )
296- || is_lint_allowed ( cx, UNNECESSARY_SAFETY_COMMENT , impl_item. hir_id ( ) )
297- {
298- return ;
299- }
300-
301- let hir:: ImplItemKind :: Const ( _, body_id) = impl_item. kind else {
276+ let hir:: ImplItemKind :: Const ( ..) = impl_item. kind else {
302277 return ;
303278 } ;
304- if body_is_unsafe_block ( cx, body_id ) {
305- return ;
306- }
279+ lint_usc_on_associated_consts ( cx, impl_item , impl_item . hir_id ( ) ) ;
280+ }
281+ }
307282
308- if let HasSafetyComment :: Yes ( pos) = item_has_safety_comment ( cx, impl_item. hir_id ( ) , impl_item. into ( ) ) {
309- let ( span, help_span) = mk_spans ( cx, impl_item. span , pos) ;
310- span_lint_and_help (
311- cx,
312- UNNECESSARY_SAFETY_COMMENT ,
313- span,
314- "associated constant has unnecessary safety comment" ,
315- Some ( help_span) ,
316- "consider removing the safety comment" ,
317- ) ;
318- }
283+ fn lint_usc_on_associated_consts < ' hir , T : Into < hir:: OwnerNode < ' hir > > > ( cx : & LateContext < ' _ > , item : T , hir_id : HirId ) {
284+ let owner_node = item. into ( ) ;
285+ let span = owner_node. span ( ) ;
286+ let Some ( body_id) = owner_node. body_id ( ) else { return } ;
287+ if in_external_macro ( cx. tcx . sess , span)
288+ || is_lint_allowed ( cx, UNNECESSARY_SAFETY_COMMENT , hir_id)
289+ || body_is_unsafe_block ( cx, body_id)
290+ {
291+ return ;
292+ }
293+
294+ if let HasSafetyComment :: Yes ( pos) = item_has_safety_comment ( cx, hir_id, owner_node) {
295+ let ( span, help_span) = mk_spans ( cx, span, pos) ;
296+ span_lint_and_help (
297+ cx,
298+ UNNECESSARY_SAFETY_COMMENT ,
299+ span,
300+ "associated constant has unnecessary safety comment" ,
301+ Some ( help_span) ,
302+ "consider removing the safety comment" ,
303+ ) ;
319304 }
320305}
321306
@@ -524,25 +509,34 @@ fn item_has_safety_comment(cx: &LateContext<'_>, hir_id: HirId, owner: hir::Owne
524509 has_safety_comment => return has_safety_comment,
525510 }
526511
527- if owner. span ( ) . ctxt ( ) != SyntaxContext :: root ( ) {
512+ if owner. span ( ) . from_expansion ( ) {
528513 return HasSafetyComment :: No ;
529514 }
530515 if let Some ( parent_node) = get_parent_node ( cx. tcx , hir_id) {
531516 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- } ,
517+ Node :: Crate ( parent_mod) => comment_start_pos (
518+ cx,
519+ parent_mod. item_ids . iter ( ) . map ( |id| id. owner_id ) ,
520+ parent_mod. spans . inner_span ,
521+ owner. def_id ( ) ,
522+ ) ,
535523 Node :: Item ( parent_item) => {
536524 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- } ,
525+ ItemKind :: Mod ( parent_mod) => comment_start_pos (
526+ cx,
527+ parent_mod. item_ids . iter ( ) . map ( |id| id. owner_id ) ,
528+ parent_item. span ,
529+ owner. def_id ( ) ,
530+ ) ,
540531 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)
532+ comment_start_pos ( cx, refs. iter ( ) . map ( |r| r. id . owner_id ) , parent_item. span , owner. def_id ( ) )
545533 } ,
534+ ItemKind :: Impl ( hir:: Impl { items, .. } ) => comment_start_pos (
535+ cx,
536+ items. iter ( ) . map ( |r| r. id . owner_id ) ,
537+ parent_item. span ,
538+ owner. def_id ( ) ,
539+ ) ,
546540 // Doesn't support impls in this position. Pretend a comment was found.
547541 _ => return HasSafetyComment :: Maybe ,
548542 }
@@ -627,71 +621,20 @@ fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> H
627621 HasSafetyComment :: Maybe
628622}
629623
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-
650624/// 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 > (
625+ fn comment_start_pos < I : Iterator < Item = OwnerId > + DoubleEndedIterator > (
652626 cx : & LateContext < ' _ > ,
653- ids : & [ T ] ,
627+ mut siblings : I ,
654628 search_span : Span ,
655- owner : OwnerNode < ' _ > ,
629+ owner_id : OwnerId ,
656630) -> 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- } )
631+ let _ = siblings. rfind ( |id| * id == owner_id) ;
632+ if let Some ( prev_sibling_id) = siblings. next_back ( ) {
633+ let prev_sibling_span = cx. tcx . hir ( ) . span ( prev_sibling_id. into ( ) ) ;
634+ walk_span_to_context ( prev_sibling_span, SyntaxContext :: root ( ) ) . map ( Span :: lo)
635+ } else {
636+ walk_span_to_context ( search_span, SyntaxContext :: root ( ) ) . map ( Span :: lo)
637+ }
695638}
696639
697640fn span_from_macro_expansion_has_safety_comment ( cx : & LateContext < ' _ > , span : Span ) -> HasSafetyComment {
@@ -730,13 +673,8 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span
730673
731674fn get_body_search_span ( cx : & LateContext < ' _ > ) -> Option < Span > {
732675 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 ) {
676+ for ( _, parent_node) in cx. tcx . hir ( ) . parent_iter ( body. hir_id ) {
737677 match parent_node {
738- Node :: Expr ( e) => span = e. span ,
739- Node :: Block ( _) | Node :: Arm ( _) | Node :: Stmt ( _) | Node :: Local ( _) => ( ) ,
740678 Node :: Item ( hir:: Item {
741679 kind : hir:: ItemKind :: Const ( ..) | ItemKind :: Static ( ..) ,
742680 ..
@@ -748,22 +686,13 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
748686 | Node :: TraitItem ( hir:: TraitItem {
749687 kind : hir:: TraitItemKind :: Const ( ..) ,
750688 ..
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 ,
689+ } ) => { } ,
690+ Node :: Item ( item) => return Some ( item. span ) ,
691+ Node :: Crate ( mod_) => return Some ( mod_. spans . inner_span ) ,
692+ _ => { } ,
764693 }
765694 }
766- Some ( span )
695+ None
767696}
768697
769698fn span_has_safety_comment ( cx : & LateContext < ' _ > , span : Span ) -> bool {
0 commit comments