Skip to content

String::as_mut_ptr is invalidated in unexected ways #158166

Description

@RalfJung

This code has UB under both Stacked and Tree Borrows:

fn main() {
    let mut s = String::with_capacity(10);
    s.push('x');
    let ptr = s.as_mut_ptr();
    unsafe { ptr.write(0x20) };
    let _ptr2 = s.as_mut_ptr(); // creates a slice that aliases with `ptr`.
    // That is considered like a read access, and since `ptr` is derived from
    // a mutable reference such a foreign read access invalidates `ptr`.
    unsafe { ptr.write(97) }; // UB
    println!("{s:?}");
}

The corresponding code with Vec is fine, because Vec::as_mut_ptr avoids invalidating previously created raw pointers to the vec's contents. String::as_mut_ptr does not exist, the code above relies on DerefMut for String and str::as_mut_ptr, which creates some extra references that cause unexpected invalidation.

Cc @rust-lang/libs-api -- would you be open to the idea of having as_mut_ptr on String as well?

Also see #97483, #106593

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Jun 20, 2026
  2. added
    C-enhancementCategory: An issue proposing an enhancement or a PR with one.
    T-libs-api[DEPRECATED; DO NOT USE]
    A-strArea: str and String
    A-raw-pointersArea: raw pointers, MaybeUninit, NonNull
    T-opsemRelevant to the opsem team
    and removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Jun 20, 2026
  3. smmalis37 commented on Jun 20, 2026

    @smmalis37
    Contributor

    Would similar inherent methods need to be added to every collection in the broader ecosystem that is able to Deref to (or otherwise present as) a slice?

  4. deleted a comment from ipezygj on Jun 21, 2026
  5. RalfJung commented on Jun 21, 2026

    @RalfJung
    MemberAuthor

    Would similar inherent methods need to be added to every collection in the broader ecosystem that is able to Deref to (or otherwise present as) a slice?

    If they want raw pointers that are not invalidated by further calls to as_mut_ptr, then yes.

    Cc @lcnr since we talked a bit about this at RustWeek.

  6. smmalis37 commented on Jun 21, 2026

    @smmalis37
    Contributor

    That feels like a rather unfortunate footgun, especially given the potential number of people it could hit (many different crate authors, and their users)

  7. RalfJung commented on Jun 21, 2026

    @RalfJung
    MemberAuthor

    Yeah, mixing references and raw pointers is fraught with peril. Not much we can do about that unless we want to give up on a good chunk of the optimizations that reference types could enable. The UCG issue for this is rust-lang/unsafe-code-guidelines#450.

    Based on what we can see with Miri, this is not very common in practice.

  8. added
    T-libsRelevant to the library team, which will review and decide on the PR/issue.
    and removed
    T-libs-api[DEPRECATED; DO NOT USE]
    on Aug 12, 2026
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-collectionsArea: `std::collections`A-raw-pointersArea: raw pointers, MaybeUninit, NonNullA-strArea: str and StringC-enhancementCategory: An issue proposing an enhancement or a PR with one.T-libsRelevant to the library team, which will review and decide on the PR/issue.T-opsemRelevant to the opsem team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions