Unnamed repository; edit this file 'description' to name the repository.
Taking a raw ref of a deref is always safe
Lukas Wirth 2024-12-18
parent 2780dfd · commit dfa4629
-rw-r--r--crates/hir-ty/src/diagnostics/unsafe_check.rs13
-rw-r--r--crates/ide-diagnostics/src/handlers/missing_unsafe.rs16
2 files changed, 27 insertions, 2 deletions
diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs
index 193aaa52c2..6bba83fac9 100644
--- a/crates/hir-ty/src/diagnostics/unsafe_check.rs
+++ b/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/crates/ide-diagnostics/src/handlers/missing_unsafe.rs b/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
index dc3dee5c9c..5f38d13570 100644
--- a/crates/ide-diagnostics/src/handlers/missing_unsafe.rs
+++ b/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;
+}
+"#,
+ )
+ }
}