summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-12-18 13:35:51 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-12-18 14:18:49 +0100
commit840f6588cc1712f6792937dd7a162b3d33aae085 (patch)
treeb4f5ce68f9fa61405df97a4bad4f1da45c1098f9
parent202008a1b8de96d2e5b6bc02d379db03a877d34d (diff)
downloadrust-840f6588cc1712f6792937dd7a162b3d33aae085.tar.gz
rust-840f6588cc1712f6792937dd7a162b3d33aae085.zip
Taking a raw ref of a deref is always safe
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs16
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs15
2 files changed, 27 insertions, 4 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
index c7f7fb7ad3d..d00b9f3e445 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs
@@ -99,10 +99,18 @@ fn walk_unsafe(
         }
         Expr::Path(path) => mark_unsafe_path(path, current.into()),
         Expr::Ref { expr, rawness: Rawness::RawPtr, mutability: _ } => {
-            if let Expr::Path(_) = body.exprs[*expr] {
-                // Do not report unsafe for `addr_of[_mut]!(EXTERN_OR_MUT_STATIC)`,
-                // see https://github.com/rust-lang/rust/pull/125834.
-                return;
+            match body.exprs[*expr] {
+                Expr::Path(_) => return,
+                // https://github.com/rust-lang/rust/pull/129248
+                // Taking a raw ref to a deref place expr is always safe.
+                Expr::UnaryOp { expr, op: UnaryOp::Deref } => {
+                    body.walk_child_exprs(expr, |child| {
+                        walk_unsafe(db, infer, body, resolver, def, child, inside_unsafe_block, unsafe_expr_cb);
+                    });
+
+                    return;
+                }
+                _ => (),
             }
         }
         Expr::MethodCall { .. } => {
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
index a630d3c7c36..796531ac6c5 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
@@ -631,4 +631,19 @@ fn main() {
 "#,
         );
     }
+
+    #[test]
+    fn raw_ref_reborrow_is_safe() {
+        check_diagnostics(
+            r#"
+fn main() {
+    let ptr: *mut i32;
+    let _addr = &raw const *ptr;
+    let local = 1;
+    let ptr = &local as *const i32;
+    let _addr = &raw const *ptr;
+}
+"#,
+        )
+    }
 }