From ef35e82ea3d40ba271e97764c5b9868f7297d318 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Mon, 1 Jan 2024 02:20:46 +0100 Subject: [PATCH] don't look for safety comments in codeblocks --- .../src/undocumented_unsafe_blocks.rs | 10 ++++++++- tests/ui/unnecessary_safety_comment.rs | 21 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index e5bc3b5a25f..add4b3e5637 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -681,11 +681,19 @@ fn text_has_safety_comment(src: &str, line_starts: &[RelativeBytePos], start_pos .filter(|(_, text)| !text.is_empty()); let (line_start, line) = lines.next()?; + let mut in_codeblock = false; // Check for a sequence of line comments. if line.starts_with("//") { let (mut line, mut line_start) = (line, line_start); loop { - if line.to_ascii_uppercase().contains("SAFETY:") { + // Don't lint if the safety comment is part of a codeblock in a doc comment. + // It may or may not be required, and we can't very easily check it (and we shouldn't, since + // the safety comment isn't referring to the node we're currently checking) + if line.trim_start_matches("///").trim_start().starts_with("```") { + in_codeblock = !in_codeblock; + } + + if line.to_ascii_uppercase().contains("SAFETY:") && !in_codeblock { return Some(start_pos + BytePos(u32::try_from(line_start).unwrap())); } match lines.next() { diff --git a/tests/ui/unnecessary_safety_comment.rs b/tests/ui/unnecessary_safety_comment.rs index d9a7ad8e56c..bdc6fa0f46b 100644 --- a/tests/ui/unnecessary_safety_comment.rs +++ b/tests/ui/unnecessary_safety_comment.rs @@ -73,4 +73,25 @@ fn main() { } } +mod issue_12048 { + pub const X: u8 = 0; + + /// Returns a pointer to five. + /// + /// # Examples + /// + /// ``` + /// use foo::point_to_five; + /// + /// let five_pointer = point_to_five(); + /// // Safety: this pointer always points to a valid five. + /// let five = unsafe { *five_pointer }; + /// assert_eq!(five, 5); + /// ``` + pub fn point_to_five() -> *const u8 { + static FIVE: u8 = 5; + &FIVE + } +} + fn main() {}