@@ -505,7 +505,8 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf
505505 } ,
506506 Node :: Stmt ( stmt) => {
507507 if let Node :: Block ( block) = cx. tcx . parent_hir_node ( stmt. hir_id ) {
508- walk_span_to_context ( block. span , SyntaxContext :: root ( ) ) . map ( Span :: lo)
508+ walk_span_to_context ( block. span , SyntaxContext :: root ( ) )
509+ . map ( |sp| CommentStartBeforeItem :: Offset ( sp. lo ( ) ) )
509510 } else {
510511 // Problem getting the parent node. Pretend a comment was found.
511512 return HasSafetyComment :: Maybe ;
@@ -518,18 +519,21 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf
518519 } ;
519520
520521 let source_map = cx. sess ( ) . source_map ( ) ;
522+ // If the comment is in the first line of the file, there is no preceding line
521523 if let Some ( comment_start) = comment_start
522524 && let Ok ( unsafe_line) = source_map. lookup_line ( item. span . lo ( ) )
523- && let Ok ( comment_start_line) = source_map. lookup_line ( comment_start)
524- && Arc :: ptr_eq ( & unsafe_line. sf , & comment_start_line. sf )
525+ && let Ok ( comment_start_line) = source_map. lookup_line ( comment_start. into ( ) )
526+ && let include_first_line_of_file = matches ! ( comment_start, CommentStartBeforeItem :: Start )
527+ && ( include_first_line_of_file || Arc :: ptr_eq ( & unsafe_line. sf , & comment_start_line. sf ) )
525528 && let Some ( src) = unsafe_line. sf . src . as_deref ( )
526529 {
527530 return if comment_start_line. line >= unsafe_line. line {
528531 HasSafetyComment :: No
529532 } else {
530533 match text_has_safety_comment (
531534 src,
532- & unsafe_line. sf . lines ( ) [ comment_start_line. line + 1 ..=unsafe_line. line ] ,
535+ & unsafe_line. sf . lines ( )
536+ [ ( comment_start_line. line + usize:: from ( !include_first_line_of_file) ) ..=unsafe_line. line ] ,
533537 unsafe_line. sf . start_pos ,
534538 ) {
535539 Some ( b) => HasSafetyComment :: Yes ( b) ,
@@ -592,28 +596,47 @@ fn stmt_has_safety_comment(
592596 HasSafetyComment :: Maybe
593597}
594598
599+ #[ derive( Clone , Copy , Debug ) ]
600+ enum CommentStartBeforeItem {
601+ Offset ( BytePos ) ,
602+ Start ,
603+ }
604+
605+ impl From < CommentStartBeforeItem > for BytePos {
606+ fn from ( value : CommentStartBeforeItem ) -> Self {
607+ match value {
608+ CommentStartBeforeItem :: Offset ( loc) => loc,
609+ CommentStartBeforeItem :: Start => BytePos ( 0 ) ,
610+ }
611+ }
612+ }
613+
595614fn comment_start_before_item_in_mod (
596615 cx : & LateContext < ' _ > ,
597616 parent_mod : & hir:: Mod < ' _ > ,
598617 parent_mod_span : Span ,
599618 item : & hir:: Item < ' _ > ,
600- ) -> Option < BytePos > {
619+ ) -> Option < CommentStartBeforeItem > {
601620 parent_mod. item_ids . iter ( ) . enumerate ( ) . find_map ( |( idx, item_id) | {
602621 if * item_id == item. item_id ( ) {
603622 if idx == 0 {
604623 // mod A { /* comment */ unsafe impl T {} ... }
605624 // ^------------------------------------------^ returns the start of this span
606625 // ^---------------------^ finally checks comments in this range
607626 if let Some ( sp) = walk_span_to_context ( parent_mod_span, SyntaxContext :: root ( ) ) {
608- return Some ( sp. lo ( ) ) ;
627+ return Some ( CommentStartBeforeItem :: Offset ( sp. lo ( ) ) ) ;
609628 }
610629 } else {
611630 // some_item /* comment */ unsafe impl T {}
612631 // ^-------^ returns the end of this span
613632 // ^---------------^ finally checks comments in this range
614633 let prev_item = cx. tcx . hir_item ( parent_mod. item_ids [ idx - 1 ] ) ;
615634 if let Some ( sp) = walk_span_to_context ( prev_item. span , SyntaxContext :: root ( ) ) {
616- return Some ( sp. hi ( ) ) ;
635+ return Some ( if sp. is_dummy ( ) {
636+ CommentStartBeforeItem :: Start
637+ } else {
638+ CommentStartBeforeItem :: Offset ( sp. hi ( ) )
639+ } ) ;
617640 }
618641 }
619642 }
@@ -668,7 +691,7 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
668691 } ) => {
669692 return maybe_mod_item
670693 . and_then ( |item| comment_start_before_item_in_mod ( cx, mod_, * span, & item) )
671- . map ( |comment_start| mod_. spans . inner_span . with_lo ( comment_start) )
694+ . map ( |comment_start| mod_. spans . inner_span . with_lo ( comment_start. into ( ) ) )
672695 . or ( Some ( * span) ) ;
673696 } ,
674697 node if let Some ( ( span, _) ) = span_and_hid_of_item_alike_node ( & node)
0 commit comments