Auto merge of #18003 - ChayimFriedman2:addr_of-static-mut, r=Veykril

Do not report missing unsafe on `addr_of[_mut]!(EXTERN_OR_MUT_STATIC)`

The compiler no longer does as well; see https://github.com/rust-lang/rust/pull/125834.

Also require unsafe when accessing `extern` `static` (other than by `addr_of!()`).

Fixes #17978.
This commit is contained in:
bors 2024-08-30 07:55:50 +00:00
commit 13ac53e73d
4 changed files with 78 additions and 7 deletions

View file

@ -5,6 +5,7 @@ use hir_def::{
body::Body, body::Body,
hir::{Expr, ExprId, UnaryOp}, hir::{Expr, ExprId, UnaryOp},
resolver::{resolver_for_expr, ResolveValueResult, Resolver, ValueNs}, resolver::{resolver_for_expr, ResolveValueResult, Resolver, ValueNs},
type_ref::Rawness,
DefWithBodyId, DefWithBodyId,
}; };
@ -87,12 +88,20 @@ fn walk_unsafe(
let g = resolver.update_to_inner_scope(db.upcast(), def, current); let g = resolver.update_to_inner_scope(db.upcast(), def, current);
let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path); let value_or_partial = resolver.resolve_path_in_value_ns(db.upcast(), path);
if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial { if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id), _)) = value_or_partial {
if db.static_data(id).mutable { let static_data = db.static_data(id);
if static_data.mutable || static_data.is_extern {
unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block }); unsafe_expr_cb(UnsafeExpr { expr: current, inside_unsafe_block });
} }
} }
resolver.reset_to_guard(g); resolver.reset_to_guard(g);
} }
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;
}
}
Expr::MethodCall { .. } => { Expr::MethodCall { .. } => {
if infer if infer
.method_resolution(current) .method_resolution(current)

View file

@ -163,6 +163,56 @@ fn main() {
); );
} }
#[test]
fn missing_unsafe_diagnostic_with_extern_static() {
check_diagnostics(
r#"
//- minicore: copy
extern "C" {
static EXTERN: i32;
static mut EXTERN_MUT: i32;
}
fn main() {
let _x = EXTERN;
//^^^^^^💡 error: this operation is unsafe and requires an unsafe function or block
let _x = EXTERN_MUT;
//^^^^^^^^^^💡 error: this operation is unsafe and requires an unsafe function or block
unsafe {
let _x = EXTERN;
let _x = EXTERN_MUT;
}
}
"#,
);
}
#[test]
fn no_unsafe_diagnostic_with_addr_of_static() {
check_diagnostics(
r#"
//- minicore: copy, addr_of
use core::ptr::{addr_of, addr_of_mut};
extern "C" {
static EXTERN: i32;
static mut EXTERN_MUT: i32;
}
static mut STATIC_MUT: i32 = 0;
fn main() {
let _x = addr_of!(EXTERN);
let _x = addr_of!(EXTERN_MUT);
let _x = addr_of!(STATIC_MUT);
let _x = addr_of_mut!(EXTERN_MUT);
let _x = addr_of_mut!(STATIC_MUT);
}
"#,
);
}
#[test] #[test]
fn no_missing_unsafe_diagnostic_with_safe_intrinsic() { fn no_missing_unsafe_diagnostic_with_safe_intrinsic() {
check_diagnostics( check_diagnostics(

View file

@ -483,8 +483,8 @@ fn main() {
file_id: FileId( file_id: FileId(
1, 1,
), ),
full_range: 632..867, full_range: 633..868,
focus_range: 693..699, focus_range: 694..700,
name: "FnOnce", name: "FnOnce",
kind: Trait, kind: Trait,
container_name: "function", container_name: "function",
@ -8479,8 +8479,8 @@ impl Iterator for S {
file_id: FileId( file_id: FileId(
1, 1,
), ),
full_range: 7801..8043, full_range: 7802..8044,
focus_range: 7866..7872, focus_range: 7867..7873,
name: "Future", name: "Future",
kind: Trait, kind: Trait,
container_name: "future", container_name: "future",
@ -8493,8 +8493,8 @@ impl Iterator for S {
file_id: FileId( file_id: FileId(
1, 1,
), ),
full_range: 8673..9172, full_range: 8674..9173,
focus_range: 8750..8758, focus_range: 8751..8759,
name: "Iterator", name: "Iterator",
kind: Trait, kind: Trait,
container_name: "iterator", container_name: "iterator",

View file

@ -65,6 +65,7 @@
//! todo: panic //! todo: panic
//! unimplemented: panic //! unimplemented: panic
//! column: //! column:
//! addr_of:
#![rustc_coherence_is_core] #![rustc_coherence_is_core]
@ -421,6 +422,17 @@ pub mod ptr {
} }
// endregion:coerce_unsized // endregion:coerce_unsized
// endregion:non_null // endregion:non_null
// region:addr_of
#[rustc_macro_transparency = "semitransparent"]
pub macro addr_of($place:expr) {
&raw const $place
}
#[rustc_macro_transparency = "semitransparent"]
pub macro addr_of_mut($place:expr) {
&raw mut $place
}
// endregion:addr_of
} }
pub mod ops { pub mod ops {