about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/diagnostics/unsafe_check.rs13
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs16
2 files changed, 27 insertions, 2 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 193aaa52c26..6bba83fac98 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
@@ -193,10 +193,19 @@ impl<'a> UnsafeVisitor<'a> {
                 self.resolver.reset_to_guard(guard);
             }
             Expr::Ref { expr, rawness: Rawness::RawPtr, mutability: _ } => {
-                if let Expr::Path(_) = self.body.exprs[*expr] {
+                match self.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;
+                    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 } => {
+                        self.body
+                            .walk_child_exprs_without_pats(expr, |child| self.walk_expr(child));
+
+                        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 dc3dee5c9ce..5f38d13570a 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
@@ -778,4 +778,20 @@ fn bar(mut v: Union2) {
             "#,
         )
     }
+
+    #[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;
+}
+"#,
+        )
+    }
 }