@@ -68,7 +68,8 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
68
68
&& !in_external_macro ( cx. tcx . sess , block. span )
69
69
&& !is_lint_allowed ( cx, UNDOCUMENTED_UNSAFE_BLOCKS , block. hir_id )
70
70
&& !is_unsafe_from_proc_macro ( cx, block. span )
71
- && !block_has_safety_comment ( cx, block)
71
+ && !block_has_safety_comment ( cx, block. span )
72
+ && !block_parents_have_safety_comment ( cx, block. hir_id )
72
73
{
73
74
let source_map = cx. tcx . sess . source_map ( ) ;
74
75
let span = if source_map. is_multiline ( block. span ) {
@@ -126,8 +127,39 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool {
126
127
. map_or ( true , |src| !src. starts_with ( "unsafe" ) )
127
128
}
128
129
130
+ // Checks if any parent {expression, statement, block, local, const, static}
131
+ // has a safety comment
132
+ fn block_parents_have_safety_comment ( cx : & LateContext < ' _ > , id : hir:: HirId ) -> bool {
133
+ for ( _, node) in cx. tcx . hir ( ) . parent_iter ( id) {
134
+ match node {
135
+ Node :: Expr ( hir:: Expr { span, .. } )
136
+ | Node :: Stmt ( hir:: Stmt {
137
+ kind :
138
+ hir:: StmtKind :: Local ( hir:: Local { span, .. } )
139
+ | hir:: StmtKind :: Expr ( hir:: Expr { span, .. } )
140
+ | hir:: StmtKind :: Semi ( hir:: Expr { span, .. } ) ,
141
+ ..
142
+ } )
143
+ | Node :: Local ( hir:: Local { span, .. } )
144
+ | Node :: Item ( hir:: Item {
145
+ kind : hir:: ItemKind :: Const ( ..) | ItemKind :: Static ( ..) ,
146
+ span,
147
+ ..
148
+ } ) => {
149
+ if span_in_body_has_safety_comment ( cx, * span) {
150
+ return true ;
151
+ }
152
+ } ,
153
+ _ => {
154
+ break ;
155
+ } ,
156
+ }
157
+ }
158
+ false
159
+ }
160
+
129
161
/// Checks if the lines immediately preceding the block contain a safety comment.
130
- fn block_has_safety_comment ( cx : & LateContext < ' _ > , block : & hir :: Block < ' _ > ) -> bool {
162
+ fn block_has_safety_comment ( cx : & LateContext < ' _ > , span : Span ) -> bool {
131
163
// This intentionally ignores text before the start of a function so something like:
132
164
// ```
133
165
// // SAFETY: reason
@@ -136,7 +168,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, block: &hir::Block<'_>) -> boo
136
168
// won't work. This is to avoid dealing with where such a comment should be place relative to
137
169
// attributes and doc comments.
138
170
139
- span_from_macro_expansion_has_safety_comment ( cx, block . span ) || span_in_body_has_safety_comment ( cx, block . span )
171
+ span_from_macro_expansion_has_safety_comment ( cx, span) || span_in_body_has_safety_comment ( cx, span)
140
172
}
141
173
142
174
/// Checks if the lines immediately preceding the item contain a safety comment.
0 commit comments