rust icon indicating copy to clipboard operation
rust copied to clipboard

Tracking issue for release notes of #125834: treat `&raw (const|mut) UNSAFE_STATIC` implied deref as safe

Open rustbot opened this issue 1 year ago • 1 comments

This issue tracks the release notes text for #125834.

  • [x] Issue is nominated for the responsible team (and T-release nomination is removed).
  • [ ] Proposed text is drafted by team responsible for underlying change.
  • [ ] Issue is nominated for release team review of clarity for wider audience.
  • [ ] Release team includes text in release notes/blog posts.

Release notes text:

The section title will be de-duplicated by the release team with other release notes issues. Prefer to use the standard titles from previous releases. More than one section can be included if needed.

# Compatibility Notes
- [treat `&raw (const|mut) UNSAFE_STATIC` implied deref as safe](https://github.com/rust-lang/rust/pull/125834)

Release blog section (if any, leave blank if no section is expected):

rustbot avatar Aug 25 '24 15:08 rustbot

Hi. I feel my PR title was very "inside baseball" terminology, and what should go into the compatibility notes might be more like one of these:

  • &raw (const|mut) is now safe to use with an UNSAFE_STATIC operand
  • Taking the address of an UNSAFE_STATIC is now safe

Possible release blog text by author of PR if you wish to note it in the release blog (whether this is appropriate or not is between you and T-compiler imo). You may wish to work it in with the raw_ref_op stabilization text as otherwise there probably will be some conceptual duplication, since these are both hitting stable together. Also feel free to trim it down, the most important part is, IMO, the "hey sprinkle around #[allow(unused_unsafe)]" part.

Taking the address of an UNSAFE_STATIC is now safe

This code is now allowed:

static mut STATIC_MUT: Type = Type::new();
extern "C" {
    static EXTERN_STATIC: Type;
}
fn main() {
     let static_mut_ptr = std::ptr::addr_of_mut!(STATIC_MUT);
     let extern_static_ptr = &raw const EXTERN_STATIC;
}

In an expression context, STATIC_MUT and EXTERN_STATIC are place expressions. Previously, the compiler's safety checks were not aware that the raw ref operator did not actually affect the operand's place, treating it as a possible read or write to a pointer. No unsafety is actually present, however, as it just creates a pointer.

This may cause problems where some unsafe blocks are now reported as unused if you deny the unused_unsafe lint, but they are now only useful on older versions. Annotate these unsafe blocks with #[allow(unused_unsafe)] if you wish to support multiple versions of Rust, as in this example diff:

 static mut STATIC_MUT: Type = Type::new();
 fn main() {
+    #[allow(unused_unsafe)]
     let static_mut_ptr = unsafe { std::ptr::addr_of_mut!(STATIC_MUT) };
 }

A future version of Rust is expected to generalize this to other expressions which would be safe in this position, not just statics.

workingjubilee avatar Aug 26 '24 05:08 workingjubilee

A future version of Rust is expected to generalize this to all instances of &raw const or &raw mut followed by a place expression, not just statics.

That's not right, &raw const (*ptr).field will have to remain unsafe.

Only &raw const *ptr can be made safe, and &raw const reference.field.

RalfJung avatar Aug 28 '24 09:08 RalfJung

T-compiler reviewed during the weekly triage meeting. We decided to go with a modification of @workingjubilee's first suggestion, tweaking to highlight this also affects addr_of(_mut)! and attempting to remove the UNSAFE_STATIC reference since we don't think that shorthand is commonly understood by the wider Rust community.

I think if there's room in the blog post and T-release wants to include it, the above content elaborating on the changes would be a great addition. We've had some churn around statics recently so highlighting the correct way to write some of this code, especially since it uses newer library functionality, would be good.

Thank you @workingjubilee and @RalfJung for drafting that!

wesleywiser avatar Aug 29 '24 14:08 wesleywiser

A future version of Rust is expected to generalize this to all instances of &raw const or &raw mut followed by a place expression, not just statics.

That's not right, &raw const (*ptr).field will have to remain unsafe.

Only &raw const *ptr can be made safe, and &raw const reference.field.

Ah okay! Then I think what I said there could instead be just

"A future version of Rust is expected to generalize this to other expressions where it's actually-safe, not just ones with statics as operands."

workingjubilee avatar Aug 29 '24 18:08 workingjubilee

Also I should note that I only included the "we'll generalize this later" remark, fwiw, because "huh, wouldn't that apply to other expressions?" was like basically the third thing everyone said while considering the PR I made, and because compiler-errors already has the PR up. :^)

workingjubilee avatar Aug 30 '24 01:08 workingjubilee