@@ -35,6 +35,7 @@ struct UnsafetyVisitor<'a, 'tcx> {
35
35
param_env : ParamEnv < ' tcx > ,
36
36
inside_adt : bool ,
37
37
warnings : & ' a mut Vec < UnusedUnsafeWarning > ,
38
+ suggest_unsafe_block : bool ,
38
39
}
39
40
40
41
impl < ' tcx > UnsafetyVisitor < ' _ , ' tcx > {
@@ -95,7 +96,13 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
95
96
SafetyContext :: UnsafeFn if unsafe_op_in_unsafe_fn_allowed => { }
96
97
SafetyContext :: UnsafeFn => {
97
98
// unsafe_op_in_unsafe_fn is disallowed
98
- kind. emit_unsafe_op_in_unsafe_fn_lint ( self . tcx , self . hir_context , span) ;
99
+ kind. emit_unsafe_op_in_unsafe_fn_lint (
100
+ self . tcx ,
101
+ self . hir_context ,
102
+ span,
103
+ self . suggest_unsafe_block ,
104
+ ) ;
105
+ self . suggest_unsafe_block = false ;
99
106
}
100
107
SafetyContext :: Safe => {
101
108
kind. emit_requires_unsafe_err (
@@ -297,6 +304,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
297
304
}
298
305
PatKind :: InlineConstant { def, .. } => {
299
306
self . visit_inner_body ( * def) ;
307
+ visit:: walk_pat ( self , pat) ;
300
308
}
301
309
_ => {
302
310
visit:: walk_pat ( self , pat) ;
@@ -545,7 +553,32 @@ impl UnsafeOpKind {
545
553
tcx : TyCtxt < ' _ > ,
546
554
hir_id : hir:: HirId ,
547
555
span : Span ,
556
+ suggest_unsafe_block : bool ,
548
557
) {
558
+ let note_non_inherited = tcx. hir ( ) . parent_iter ( hir_id) . find ( |( id, _) | {
559
+ if let Some ( sig) = tcx. hir ( ) . fn_sig_by_hir_id ( * id)
560
+ && sig. header . is_unsafe ( )
561
+ {
562
+ true
563
+ } else {
564
+ false
565
+ }
566
+ } ) ;
567
+ let unsafe_not_inherited_note = if let Some ( ( id, _) ) = note_non_inherited {
568
+ suggest_unsafe_block. then ( || {
569
+ let span = tcx. hir ( ) . span ( id) ;
570
+ let signature_span = tcx. sess . source_map ( ) . guess_head_span ( span) ;
571
+ let body = tcx. hir ( ) . body_owned_by ( hir_id. owner . def_id ) ;
572
+ let body_span = tcx. hir ( ) . body ( body) . value . span ;
573
+ UnsafeNotInheritedLintNote {
574
+ signature_span,
575
+ body_start : tcx. sess . source_map ( ) . start_point ( body_span) . shrink_to_hi ( ) ,
576
+ body_end : tcx. sess . source_map ( ) . end_point ( body_span) . shrink_to_lo ( ) ,
577
+ }
578
+ } )
579
+ } else {
580
+ None
581
+ } ;
549
582
// FIXME: ideally we would want to trim the def paths, but this is not
550
583
// feasible with the current lint emission API (see issue #106126).
551
584
match self {
@@ -556,61 +589,89 @@ impl UnsafeOpKind {
556
589
UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe {
557
590
span,
558
591
function : & with_no_trimmed_paths ! ( tcx. def_path_str( * did) ) ,
592
+ unsafe_not_inherited_note,
559
593
} ,
560
594
) ,
561
595
CallToUnsafeFunction ( None ) => tcx. emit_spanned_lint (
562
596
UNSAFE_OP_IN_UNSAFE_FN ,
563
597
hir_id,
564
598
span,
565
- UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { span } ,
599
+ UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless {
600
+ span,
601
+ unsafe_not_inherited_note,
602
+ } ,
566
603
) ,
567
604
UseOfInlineAssembly => tcx. emit_spanned_lint (
568
605
UNSAFE_OP_IN_UNSAFE_FN ,
569
606
hir_id,
570
607
span,
571
- UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { span } ,
608
+ UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe {
609
+ span,
610
+ unsafe_not_inherited_note,
611
+ } ,
572
612
) ,
573
613
InitializingTypeWith => tcx. emit_spanned_lint (
574
614
UNSAFE_OP_IN_UNSAFE_FN ,
575
615
hir_id,
576
616
span,
577
- UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { span } ,
617
+ UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe {
618
+ span,
619
+ unsafe_not_inherited_note,
620
+ } ,
578
621
) ,
579
622
UseOfMutableStatic => tcx. emit_spanned_lint (
580
623
UNSAFE_OP_IN_UNSAFE_FN ,
581
624
hir_id,
582
625
span,
583
- UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { span } ,
626
+ UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe {
627
+ span,
628
+ unsafe_not_inherited_note,
629
+ } ,
584
630
) ,
585
631
UseOfExternStatic => tcx. emit_spanned_lint (
586
632
UNSAFE_OP_IN_UNSAFE_FN ,
587
633
hir_id,
588
634
span,
589
- UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { span } ,
635
+ UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe {
636
+ span,
637
+ unsafe_not_inherited_note,
638
+ } ,
590
639
) ,
591
640
DerefOfRawPointer => tcx. emit_spanned_lint (
592
641
UNSAFE_OP_IN_UNSAFE_FN ,
593
642
hir_id,
594
643
span,
595
- UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { span } ,
644
+ UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe {
645
+ span,
646
+ unsafe_not_inherited_note,
647
+ } ,
596
648
) ,
597
649
AccessToUnionField => tcx. emit_spanned_lint (
598
650
UNSAFE_OP_IN_UNSAFE_FN ,
599
651
hir_id,
600
652
span,
601
- UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { span } ,
653
+ UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe {
654
+ span,
655
+ unsafe_not_inherited_note,
656
+ } ,
602
657
) ,
603
658
MutationOfLayoutConstrainedField => tcx. emit_spanned_lint (
604
659
UNSAFE_OP_IN_UNSAFE_FN ,
605
660
hir_id,
606
661
span,
607
- UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { span } ,
662
+ UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe {
663
+ span,
664
+ unsafe_not_inherited_note,
665
+ } ,
608
666
) ,
609
667
BorrowOfLayoutConstrainedField => tcx. emit_spanned_lint (
610
668
UNSAFE_OP_IN_UNSAFE_FN ,
611
669
hir_id,
612
670
span,
613
- UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { span } ,
671
+ UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe {
672
+ span,
673
+ unsafe_not_inherited_note,
674
+ } ,
614
675
) ,
615
676
CallToFunctionWith ( did) => tcx. emit_spanned_lint (
616
677
UNSAFE_OP_IN_UNSAFE_FN ,
@@ -619,6 +680,7 @@ impl UnsafeOpKind {
619
680
UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe {
620
681
span,
621
682
function : & with_no_trimmed_paths ! ( tcx. def_path_str( * did) ) ,
683
+ unsafe_not_inherited_note,
622
684
} ,
623
685
) ,
624
686
}
@@ -833,6 +895,7 @@ pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
833
895
param_env : tcx. param_env ( def) ,
834
896
inside_adt : false ,
835
897
warnings : & mut warnings,
898
+ suggest_unsafe_block : true ,
836
899
} ;
837
900
visitor. visit_expr ( & thir[ expr] ) ;
838
901
0 commit comments