Skip to content

Commit 45b38ba

Browse files
committed
recognize safety comments inside blocks and on same line in macros
1 parent f39e7e0 commit 45b38ba

File tree

4 files changed

+249
-138
lines changed

4 files changed

+249
-138
lines changed

clippy_lints/src/undocumented_unsafe_blocks.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
115115
&& !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)
116116
&& !is_unsafe_from_proc_macro(cx, block.span)
117117
&& !block_has_safety_comment(cx, block.span, self.accept_comment_above_attributes)
118+
&& !block_has_inner_safety_comment(cx, block.span)
118119
&& !block_parents_have_safety_comment(
119120
self.accept_comment_above_statement,
120121
self.accept_comment_above_attributes,
@@ -839,6 +840,20 @@ fn text_has_safety_comment(
839840
}
840841
}
841842
}
843+
// Check for a comment that appears after other code on the same line (e.g., `let x =// SAFETY:`)
844+
// This handles cases in macros where the comment is on the same line as preceding code.
845+
// We only check the first (immediate preceding) line for this pattern.
846+
let comment_start = [line.find("//"), line.find("/*")].into_iter().flatten().min();
847+
if let Some(comment_start) = comment_start
848+
&& let Some(safety_offset) = line[comment_start..].to_ascii_uppercase().find("SAFETY:")
849+
{
850+
return HasSafetyComment::Yes(
851+
start_pos
852+
+ BytePos(u32::try_from(line_start).unwrap())
853+
+ BytePos(u32::try_from(comment_start + safety_offset).unwrap()),
854+
false,
855+
);
856+
}
842857
// No line comments; look for the start of a block comment.
843858
// This will only find them if they are at the start of a line.
844859
let (mut line_start, mut line) = (line_start, line);
@@ -894,3 +909,20 @@ fn is_const_or_static(node: &Node<'_>) -> bool {
894909
})
895910
)
896911
}
912+
913+
fn block_has_inner_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
914+
let source_map = cx.sess().source_map();
915+
if let Ok(src) = source_map.span_to_snippet(span)
916+
&& let Some(after_brace) = src
917+
.strip_prefix("unsafe")
918+
.and_then(|s| s.trim_start().strip_prefix('{'))
919+
&& let Some(comment) = after_brace
920+
.trim_start()
921+
.strip_prefix("//")
922+
.or_else(|| after_brace.trim_start().strip_prefix("/*"))
923+
{
924+
comment.trim_start().to_ascii_uppercase().starts_with("SAFETY:")
925+
} else {
926+
false
927+
}
928+
}

0 commit comments

Comments
 (0)