Skip to content

Tracking Issue for raw_ref_macros #73394

Description

@RalfJung

This is a tracking issue for the macro version of raw_ref_op (#64490).
The feature gate for the issue is #![feature(raw_ref_macros)].

About tracking issues

Tracking issues are used to record the overall progress of implementation.
They are also uses as hubs connecting to other relevant issues, e.g., bugs or open design questions.
A tracking issue is however not meant for large scale discussion, questions, or bug reports about a feature.
Instead, open a dedicated issue for the specific matter and add the relevant feature gate label.

Steps

Unresolved Questions

Implementation history

Activity

  1. added
    T-langRelevant to the language team
    T-libs-api[DEPRECATED; DO NOT USE]
    C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFC
    F-raw_ref_op`#![feature(raw_ref_op)]`
    on Jun 16, 2020
  2. jonas-schievink commented on Jul 14, 2020

    @jonas-schievink
    Contributor

    rustdoc displays the macro in core::raw_mut https://doc.rust-lang.org/nightly/core/macro.raw_mut.html

  3. RalfJung commented on Jul 15, 2020

    @RalfJung
    MemberAuthor

    Sounds like a rustdoc bug, thanks for pointing that out.

    Reported as #74355.

  4. RalfJung commented on Jul 27, 2020

    @RalfJung
    MemberAuthor

    Stabilization report

    (Is there a template for these? I am entirely making this up.^^)

    I'd like to propose stabilizing the raw_ref_macros feature. This feature guard two macros, core::ptr::raw_const! and core::ptr::raw_mut!. Both of these macros take path expressions and their effect is to create a raw pointer as described in RFC 2582.

    This exposes a new primitive language ability: creating a raw pointer to something without going through an intermediate reference. This operation has been talked about in the Rust community for at least as long as I am around (I recall @arielb1 suggesting something like it). Example use cases that require such an operation are a general offset_of! macro, and creating pointers to unaligned fields of a packed struct. In particular, stabilizing this feature one way or another is crucial to unblock progress on one of the oldest open soundness bugs, #27060.

    The aforementioned RFC proposes a new primitive syntax for these macros. However, we are not yet ready to commit to a stable syntax for these operations -- but we still would like to expose this ability to stable code. Following precedent like the try! macro, we thus propose to stabilize this feature through macros first, which is what the raw_ref_macros feature does.

    Existing users

    The raw_ref operation (whether through the syntax or the macro) is already seeing some use in-tree, e.g. in #73845 and #73971. Out-of-tree, Gilnaa/memoffset#43 ports the popular memoffset crate to use this operation.

    An earlier crater experiment found around 50 crates that created references to unaligned fields of a packed struct. Some of those can probably be fixed by making copies instead of creating references (a common issue when using such fields in println! or comparison operations), but other likely truly need a pointer to that field, which currently cannot be created in a UB-free way.

    Implementation history

    Potential blockers/issues

  5. nikomatsakis commented on Jul 27, 2020

    @nikomatsakis
    Contributor

    @RalfJung there is no template I'm aware of, I've been meaning to make one for some time

  6. nikomatsakis commented on Jul 27, 2020

    @nikomatsakis
    Contributor

    @rfcbot fcp merge

    Following @RalfJung's excellent report, I propose that we stabilize the raw_const and raw_mut macros.

  7. rfcbot commented on Jul 27, 2020

    @rfcbot

    Team member @nikomatsakis has proposed to merge this. The next step is review by the rest of the tagged team members:

    Concerns:

    Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

    See this document for info about what commands tagged team members can give me.

  8. added
    proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
    disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.
    on Jul 27, 2020
  9. nikomatsakis commented on Jul 27, 2020

    @nikomatsakis
    Contributor

    One thing to note here is that we are stabilizing things implemented with a macro, I believe -- I would appreciate it if @petrochenkov would cast an eye over the definitions to "approve" them =)

    I see they include a #[rustc_macro_transparency = "semitransparent"] attribute, which I think @petrochenkov requested, though I have no real idea just what it does. I would presume that, in terms of hygiene, these macros would be a rather simple case, since they don't introduce any binders. =)

    rust/src/libcore/ptr/mod.rs

    Lines 1477 to 1542 in 4a90e36

    /// Create a `const` raw pointer to a place, without creating an intermediate reference.
    ///
    /// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
    /// and points to initialized data. For cases where those requirements do not hold,
    /// raw pointers should be used instead. However, `&expr as *const _` creates a reference
    /// before casting it to a raw pointer, and that reference is subject to the same rules
    /// as all other references. This macro can create a raw pointer *without* creating
    /// a reference first.
    ///
    /// # Example
    ///
    /// ```
    /// #![feature(raw_ref_macros)]
    /// use std::ptr;
    ///
    /// #[repr(packed)]
    /// struct Packed {
    /// f1: u8,
    /// f2: u16,
    /// }
    ///
    /// let packed = Packed { f1: 1, f2: 2 };
    /// // `&packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
    /// let raw_f2 = ptr::raw_const!(packed.f2);
    /// assert_eq!(unsafe { raw_f2.read_unaligned() }, 2);
    /// ```
    #[unstable(feature = "raw_ref_macros", issue = "73394")]
    #[rustc_macro_transparency = "semitransparent"]
    #[allow_internal_unstable(raw_ref_op)]
    pub macro raw_const($e:expr) {
    &raw const $e
    }
    /// Create a `mut` raw pointer to a place, without creating an intermediate reference.
    ///
    /// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
    /// and points to initialized data. For cases where those requirements do not hold,
    /// raw pointers should be used instead. However, `&mut expr as *mut _` creates a reference
    /// before casting it to a raw pointer, and that reference is subject to the same rules
    /// as all other references. This macro can create a raw pointer *without* creating
    /// a reference first.
    ///
    /// # Example
    ///
    /// ```
    /// #![feature(raw_ref_macros)]
    /// use std::ptr;
    ///
    /// #[repr(packed)]
    /// struct Packed {
    /// f1: u8,
    /// f2: u16,
    /// }
    ///
    /// let mut packed = Packed { f1: 1, f2: 2 };
    /// // `&mut packed.f2` would create an unaligned reference, and thus be Undefined Behavior!
    /// let raw_f2 = ptr::raw_mut!(packed.f2);
    /// unsafe { raw_f2.write_unaligned(42); }
    /// assert_eq!({packed.f2}, 42); // `{...}` forces copying the field instead of creating a reference.
    /// ```
    #[unstable(feature = "raw_ref_macros", issue = "73394")]
    #[rustc_macro_transparency = "semitransparent"]
    #[allow_internal_unstable(raw_ref_op)]
    pub macro raw_mut($e:expr) {
    &raw mut $e
    }

  10. 22 remaining items

  11. added
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    and removed
    proposed-final-comment-periodProposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off.
    on Oct 26, 2020
  12. rfcbot commented on Oct 26, 2020

    @rfcbot

    🔔 This is now entering its final comment period, as per the review above. 🔔

  13. added and removed
    final-comment-periodIn the final comment period and will be merged soon unless new substantive objections are raised.
    on Nov 5, 2020
  14. rfcbot commented on Nov 5, 2020

    @rfcbot

    The final comment period, with a disposition to merge, as per the review above, is now complete.

    As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

    The RFC will be merged soon.

  15. nikomatsakis commented on Nov 5, 2020

    @nikomatsakis
    Contributor

    Woohoo! I guess we need a stabilization PR now?

  16. RalfJung commented on Nov 5, 2020

    @RalfJung
    MemberAuthor

    🎉

    However, if we stabilize while #74355 is unresolved, its docs will be rendered incorrectly.

  17. RalfJung commented on Dec 26, 2020

    @RalfJung
    MemberAuthor

    FWIW, I am still having doubt about the macro names, but no better names have been suggested yet either. raw_const! in particular sounds like const is the subject here... usually this will probably be written as ptr::raw_const!, but that is still strange.

    const_raw! might be better? At least now const is unambiguously an adjective. That also works for mut_raw!. But usually, mut is a suffix, not a prefix. @rust-lang/libs any ideas?

  18. RalfJung commented on Jan 4, 2021

    @RalfJung
    MemberAuthor

    Another option might be ptr::const_addr_of! and ptr::mut_addr_of!. These at least indicate what the operation is doing.

  19. added a commit that references this issue on Jan 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-raw-pointersArea: raw pointers, MaybeUninit, NonNullB-unstableBlocker: Implemented in the nightly compiler and unstable.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCF-raw_ref_op`#![feature(raw_ref_op)]`I-libs-radarLibs issues that are tracked on the team's radar.T-langRelevant to the language teamT-libs-api[DEPRECATED; DO NOT USE]disposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions