@@ -35,6 +35,10 @@ struct UnsafetyVisitor<'a, 'tcx> {
3535    param_env :  ParamEnv < ' tcx > , 
3636    inside_adt :  bool , 
3737    warnings :  & ' a  mut  Vec < UnusedUnsafeWarning > , 
38+ 
39+     /// Flag to ensure that we only suggest wrapping the entire function body in 
40+ /// an unsafe block once. 
41+ suggest_unsafe_block :  bool , 
3842} 
3943
4044impl < ' tcx >  UnsafetyVisitor < ' _ ,  ' tcx >  { 
@@ -95,7 +99,13 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
9599            SafetyContext :: UnsafeFn  if  unsafe_op_in_unsafe_fn_allowed => { } 
96100            SafetyContext :: UnsafeFn  => { 
97101                // unsafe_op_in_unsafe_fn is disallowed 
98-                 kind. emit_unsafe_op_in_unsafe_fn_lint ( self . tcx ,  self . hir_context ,  span) ; 
102+                 kind. emit_unsafe_op_in_unsafe_fn_lint ( 
103+                     self . tcx , 
104+                     self . hir_context , 
105+                     span, 
106+                     self . suggest_unsafe_block , 
107+                 ) ; 
108+                 self . suggest_unsafe_block  = false ; 
99109            } 
100110            SafetyContext :: Safe  => { 
101111                kind. emit_requires_unsafe_err ( 
@@ -297,6 +307,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
297307            } 
298308            PatKind :: InlineConstant  {  def,  .. }  => { 
299309                self . visit_inner_body ( * def) ; 
310+                 visit:: walk_pat ( self ,  pat) ; 
300311            } 
301312            _ => { 
302313                visit:: walk_pat ( self ,  pat) ; 
@@ -545,7 +556,22 @@ impl UnsafeOpKind {
545556        tcx :  TyCtxt < ' _ > , 
546557        hir_id :  hir:: HirId , 
547558        span :  Span , 
559+         suggest_unsafe_block :  bool , 
548560    )  { 
561+         let  parent_id = tcx. hir ( ) . get_parent_item ( hir_id) ; 
562+         let  parent_owner = tcx. hir ( ) . owner ( parent_id) ; 
563+         let  should_suggest = parent_owner. fn_sig ( ) . map_or ( false ,  |sig| sig. header . is_unsafe ( ) ) ; 
564+         let  unsafe_not_inherited_note = if  should_suggest { 
565+             suggest_unsafe_block. then ( || { 
566+                 let  body_span = tcx. hir ( ) . body ( parent_owner. body_id ( ) . unwrap ( ) ) . value . span ; 
567+                 UnsafeNotInheritedLintNote  { 
568+                     signature_span :  tcx. def_span ( parent_id. def_id ) , 
569+                     body_span, 
570+                 } 
571+             } ) 
572+         }  else  { 
573+             None 
574+         } ; 
549575        // FIXME: ideally we would want to trim the def paths, but this is not 
550576        // feasible with the current lint emission API (see issue #106126). 
551577        match  self  { 
@@ -556,61 +582,89 @@ impl UnsafeOpKind {
556582                UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe  { 
557583                    span, 
558584                    function :  & with_no_trimmed_paths ! ( tcx. def_path_str( * did) ) , 
585+                     unsafe_not_inherited_note, 
559586                } , 
560587            ) , 
561588            CallToUnsafeFunction ( None )  => tcx. emit_spanned_lint ( 
562589                UNSAFE_OP_IN_UNSAFE_FN , 
563590                hir_id, 
564591                span, 
565-                 UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless  {  span } , 
592+                 UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless  { 
593+                     span, 
594+                     unsafe_not_inherited_note, 
595+                 } , 
566596            ) , 
567597            UseOfInlineAssembly  => tcx. emit_spanned_lint ( 
568598                UNSAFE_OP_IN_UNSAFE_FN , 
569599                hir_id, 
570600                span, 
571-                 UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe  {  span } , 
601+                 UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe  { 
602+                     span, 
603+                     unsafe_not_inherited_note, 
604+                 } , 
572605            ) , 
573606            InitializingTypeWith  => tcx. emit_spanned_lint ( 
574607                UNSAFE_OP_IN_UNSAFE_FN , 
575608                hir_id, 
576609                span, 
577-                 UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe  {  span } , 
610+                 UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe  { 
611+                     span, 
612+                     unsafe_not_inherited_note, 
613+                 } , 
578614            ) , 
579615            UseOfMutableStatic  => tcx. emit_spanned_lint ( 
580616                UNSAFE_OP_IN_UNSAFE_FN , 
581617                hir_id, 
582618                span, 
583-                 UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe  {  span } , 
619+                 UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe  { 
620+                     span, 
621+                     unsafe_not_inherited_note, 
622+                 } , 
584623            ) , 
585624            UseOfExternStatic  => tcx. emit_spanned_lint ( 
586625                UNSAFE_OP_IN_UNSAFE_FN , 
587626                hir_id, 
588627                span, 
589-                 UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe  {  span } , 
628+                 UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe  { 
629+                     span, 
630+                     unsafe_not_inherited_note, 
631+                 } , 
590632            ) , 
591633            DerefOfRawPointer  => tcx. emit_spanned_lint ( 
592634                UNSAFE_OP_IN_UNSAFE_FN , 
593635                hir_id, 
594636                span, 
595-                 UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe  {  span } , 
637+                 UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe  { 
638+                     span, 
639+                     unsafe_not_inherited_note, 
640+                 } , 
596641            ) , 
597642            AccessToUnionField  => tcx. emit_spanned_lint ( 
598643                UNSAFE_OP_IN_UNSAFE_FN , 
599644                hir_id, 
600645                span, 
601-                 UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe  {  span } , 
646+                 UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe  { 
647+                     span, 
648+                     unsafe_not_inherited_note, 
649+                 } , 
602650            ) , 
603651            MutationOfLayoutConstrainedField  => tcx. emit_spanned_lint ( 
604652                UNSAFE_OP_IN_UNSAFE_FN , 
605653                hir_id, 
606654                span, 
607-                 UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe  {  span } , 
655+                 UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe  { 
656+                     span, 
657+                     unsafe_not_inherited_note, 
658+                 } , 
608659            ) , 
609660            BorrowOfLayoutConstrainedField  => tcx. emit_spanned_lint ( 
610661                UNSAFE_OP_IN_UNSAFE_FN , 
611662                hir_id, 
612663                span, 
613-                 UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe  {  span } , 
664+                 UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe  { 
665+                     span, 
666+                     unsafe_not_inherited_note, 
667+                 } , 
614668            ) , 
615669            CallToFunctionWith ( did)  => tcx. emit_spanned_lint ( 
616670                UNSAFE_OP_IN_UNSAFE_FN , 
@@ -619,6 +673,7 @@ impl UnsafeOpKind {
619673                UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe  { 
620674                    span, 
621675                    function :  & with_no_trimmed_paths ! ( tcx. def_path_str( * did) ) , 
676+                     unsafe_not_inherited_note, 
622677                } , 
623678            ) , 
624679        } 
@@ -833,6 +888,7 @@ pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
833888        param_env :  tcx. param_env ( def) , 
834889        inside_adt :  false , 
835890        warnings :  & mut  warnings, 
891+         suggest_unsafe_block :  true , 
836892    } ; 
837893    visitor. visit_expr ( & thir[ expr] ) ; 
838894
0 commit comments