@@ -505,7 +505,8 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf
505
505
} ,
506
506
Node :: Stmt ( stmt) => {
507
507
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 ( ) ) )
509
510
} else {
510
511
// Problem getting the parent node. Pretend a comment was found.
511
512
return HasSafetyComment :: Maybe ;
@@ -518,18 +519,21 @@ fn item_has_safety_comment(cx: &LateContext<'_>, item: &hir::Item<'_>) -> HasSaf
518
519
} ;
519
520
520
521
let source_map = cx. sess ( ) . source_map ( ) ;
522
+ // If the comment is in the first line of the file, there is no preceding line
521
523
if let Some ( comment_start) = comment_start
522
524
&& 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 ) )
525
528
&& let Some ( src) = unsafe_line. sf . src . as_deref ( )
526
529
{
527
530
return if comment_start_line. line >= unsafe_line. line {
528
531
HasSafetyComment :: No
529
532
} else {
530
533
match text_has_safety_comment (
531
534
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 ] ,
533
537
unsafe_line. sf . start_pos ,
534
538
) {
535
539
Some ( b) => HasSafetyComment :: Yes ( b) ,
@@ -592,28 +596,47 @@ fn stmt_has_safety_comment(
592
596
HasSafetyComment :: Maybe
593
597
}
594
598
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
+
595
614
fn comment_start_before_item_in_mod (
596
615
cx : & LateContext < ' _ > ,
597
616
parent_mod : & hir:: Mod < ' _ > ,
598
617
parent_mod_span : Span ,
599
618
item : & hir:: Item < ' _ > ,
600
- ) -> Option < BytePos > {
619
+ ) -> Option < CommentStartBeforeItem > {
601
620
parent_mod. item_ids . iter ( ) . enumerate ( ) . find_map ( |( idx, item_id) | {
602
621
if * item_id == item. item_id ( ) {
603
622
if idx == 0 {
604
623
// mod A { /* comment */ unsafe impl T {} ... }
605
624
// ^------------------------------------------^ returns the start of this span
606
625
// ^---------------------^ finally checks comments in this range
607
626
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 ( ) ) ) ;
609
628
}
610
629
} else {
611
630
// some_item /* comment */ unsafe impl T {}
612
631
// ^-------^ returns the end of this span
613
632
// ^---------------^ finally checks comments in this range
614
633
let prev_item = cx. tcx . hir_item ( parent_mod. item_ids [ idx - 1 ] ) ;
615
634
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
+ } ) ;
617
640
}
618
641
}
619
642
}
@@ -668,7 +691,7 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
668
691
} ) => {
669
692
return maybe_mod_item
670
693
. 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 ( ) ) )
672
695
. or ( Some ( * span) ) ;
673
696
} ,
674
697
node if let Some ( ( span, _) ) = span_and_hid_of_item_alike_node ( & node)
0 commit comments