about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJ-ZhengLi <lizheng135@huawei.com>2024-07-10 11:34:24 +0800
committeryanglsh <yanglsh@shanghaitech.edu.cn>2025-03-01 20:33:24 +0800
commitd395646a60f91ff40baebc9f0cd032cb182ea916 (patch)
tree82b86e98d0434dc022d4463eb00405201b441f19
parent1419ac2982e8c33496f896cc98c4bb4b14c94813 (diff)
downloadrust-d395646a60f91ff40baebc9f0cd032cb182ea916.tar.gz
rust-d395646a60f91ff40baebc9f0cd032cb182ea916.zip
fix [`undocumented_unsafe_blocks`] FP with trait/impl items
-rw-r--r--clippy_lints/src/undocumented_unsafe_blocks.rs82
-rw-r--r--tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr42
-rw-r--r--tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr42
-rw-r--r--tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs41
4 files changed, 171 insertions, 36 deletions
diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs
index 746bf018bcc..917e7919c12 100644
--- a/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -350,12 +350,13 @@ fn block_parents_have_safety_comment(
     let (span, hir_id) = match cx.tcx.parent_hir_node(id) {
         Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) {
             Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
-            Node::Item(hir::Item {
-                kind: ItemKind::Const(..) | ItemKind::Static(..),
-                span,
-                owner_id,
-                ..
-            }) => (*span, cx.tcx.local_def_id_to_hir_id(owner_id.def_id)),
+
+            node if let Some((span, hir_id)) = span_and_hid_of_item_alike_node(&node)
+                && is_const_or_static(&node) =>
+            {
+                (span, hir_id)
+            },
+
             _ => {
                 if is_branchy(expr) {
                     return false;
@@ -371,12 +372,13 @@ fn block_parents_have_safety_comment(
             ..
         })
         | Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
-        Node::Item(hir::Item {
-            kind: ItemKind::Const(..) | ItemKind::Static(..),
-            span,
-            owner_id,
-            ..
-        }) => (*span, cx.tcx.local_def_id_to_hir_id(owner_id.def_id)),
+
+        node if let Some((span, hir_id)) = span_and_hid_of_item_alike_node(&node)
+            && is_const_or_static(&node) =>
+        {
+            (span, hir_id)
+        },
+
         _ => return false,
     };
     // if unsafe block is part of a let/const/static statement,
@@ -604,31 +606,18 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span
 
 fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
     let body = cx.enclosing_body?;
-    let mut span = cx.tcx.hir_body(body).value.span;
-    let mut maybe_global_var = false;
-    for (_, node) in cx.tcx.hir_parent_iter(body.hir_id) {
-        match node {
-            Node::Expr(e) => span = e.span,
-            Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::LetStmt(_) => (),
-            Node::Item(hir::Item {
-                kind: ItemKind::Const(..) | ItemKind::Static(..),
-                ..
-            }) => maybe_global_var = true,
-            Node::Item(hir::Item {
-                kind: ItemKind::Mod(_),
-                span: item_span,
-                ..
-            }) => {
-                span = *item_span;
-                break;
+    for (_, parent_node) in cx.tcx.hir_parent_iter(body.hir_id) {
+        match parent_node {
+            Node::Crate(mod_) => return Some(mod_.spans.inner_span),
+            node if let Some((span, _)) = span_and_hid_of_item_alike_node(&node)
+                && !is_const_or_static(&node) =>
+            {
+                return Some(span);
             },
-            Node::Crate(mod_) if maybe_global_var => {
-                span = mod_.spans.inner_span;
-            },
-            _ => break,
+            _ => {},
         }
     }
-    Some(span)
+    None
 }
 
 fn span_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {
@@ -717,3 +706,28 @@ fn text_has_safety_comment(src: &str, line_starts: &[RelativeBytePos], start_pos
         }
     }
 }
+
+fn span_and_hid_of_item_alike_node(node: &Node<'_>) -> Option<(Span, HirId)> {
+    match node {
+        Node::Item(item) => Some((item.span, item.owner_id.into())),
+        Node::TraitItem(ti) => Some((ti.span, ti.owner_id.into())),
+        Node::ImplItem(ii) => Some((ii.span, ii.owner_id.into())),
+        _ => None,
+    }
+}
+
+fn is_const_or_static(node: &Node<'_>) -> bool {
+    matches!(
+        node,
+        Node::Item(hir::Item {
+            kind: ItemKind::Const(..) | ItemKind::Static(..),
+            ..
+        }) | Node::ImplItem(hir::ImplItem {
+            kind: hir::ImplItemKind::Const(..),
+            ..
+        }) | Node::TraitItem(hir::TraitItem {
+            kind: hir::TraitItemKind::Const(..),
+            ..
+        })
+    )
+}
diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
index 32ed78151d2..d3585322bb9 100644
--- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
+++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
@@ -310,5 +310,45 @@ LL |             let bar = unsafe {};
    |
    = help: consider adding a safety comment on the preceding line
 
-error: aborting due to 35 previous errors
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:592:52
+   |
+LL |         const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 };
+   |                                                    ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:601:41
+   |
+LL |         const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 };
+   |                                         ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:611:42
+   |
+LL |         const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 };
+   |                                          ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:616:40
+   |
+LL |         const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 };
+   |                                        ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:627:9
+   |
+LL |         unsafe { here_is_another_variable_with_long_name };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: aborting due to 40 previous errors
 
diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
index 83a6986addf..9ded7fb407a 100644
--- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
+++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
@@ -390,5 +390,45 @@ LL |     unsafe {}
    |
    = help: consider adding a safety comment on the preceding line
 
-error: aborting due to 45 previous errors
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:592:52
+   |
+LL |         const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 };
+   |                                                    ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:601:41
+   |
+LL |         const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 };
+   |                                         ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:611:42
+   |
+LL |         const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 };
+   |                                          ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:616:40
+   |
+LL |         const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 };
+   |                                        ^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs:627:9
+   |
+LL |         unsafe { here_is_another_variable_with_long_name };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: aborting due to 50 previous errors
 
diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
index 6a3fda3df5c..582f31f3bba 100644
--- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
+++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
@@ -632,4 +632,45 @@ mod issue_11246 {
 // Safety: Another safety comment
 const FOO: () = unsafe {};
 
+// trait items and impl items
+mod issue_11709 {
+    trait MyTrait {
+        const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 0 };
+        //~^ ERROR: unsafe block missing a safety comment
+
+        // SAFETY: safe
+        const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 1 };
+
+        // SAFETY: unrelated
+        unsafe fn unsafe_fn() {}
+
+        const NO_SAFETY_IN_TRAIT: i32 = unsafe { 1 };
+        //~^ ERROR: unsafe block missing a safety comment
+    }
+
+    struct UnsafeStruct;
+
+    impl MyTrait for UnsafeStruct {
+        // SAFETY: safe in this impl
+        const NO_SAFETY_IN_TRAIT_BUT_IN_IMPL: u8 = unsafe { 2 };
+
+        const HAS_SAFETY_IN_TRAIT: i32 = unsafe { 3 };
+        //~^ ERROR: unsafe block missing a safety comment
+    }
+
+    impl UnsafeStruct {
+        const NO_SAFETY_IN_IMPL: i32 = unsafe { 1 };
+        //~^ ERROR: unsafe block missing a safety comment
+    }
+}
+
+fn issue_13024() {
+    let mut just_a_simple_variable_with_a_very_long_name_that_has_seventy_eight_characters = 0;
+    let here_is_another_variable_with_long_name = 100;
+
+    // SAFETY: good
+    just_a_simple_variable_with_a_very_long_name_that_has_seventy_eight_characters =
+        unsafe { here_is_another_variable_with_long_name };
+}
+
 fn main() {}