Skip to content

We should decide whether take_mut is sound #161168

Description

@RalfJung

The take_mut and replace_with crates have been around since forever and, despite being unmaintained, has tons of downloads. I am sure variants of this pattern have been copied into many other places; at least one such copy exists in the standard library. However, take_mut is in a soundness conflict with other patterns, such as partial_borrow and the WontDrop from this Zulip comment. Both of those rely on mutable references being "pinned" in some sense, while wanting to avoid the overhead of Pin to make that pinning explicit in the type system.

This means the soundness status of take_mut is undecided. (Note that even if take_mut is unsound, some instances of the pattern may be sound, so e.g. the use in the standard library may still be fine. It just means the safety argument for why that code is fine needs to be more complicated than it currently is.) I think it is harmful to leave the ecosystem in limbo about whether this pattern is sound. We should officially decide one way or the other, by blessing one of the APIs as sound. The most direct way of doing that would be having something in the standard library, but we could also consider having a collection of "operations we consider sound but not common enough to have in the standard library" somewhere. Not sure where.

My personal preference would be to say that take_mut/replace_with are sound. I consider this "natural" since in a formal model of Rust (such as RustBelt), if you don't do anything special for mutable references, this is what will happen. It falls out of the fact that all types are movable. We have pinning any maybe eventually !Move types to properly indicate when something should not be movable.

This has previously been suggested in rust-lang/rfcs#1736 and was closed (10 years ago) because it was considered a footgun to have such implicit aborts in the standard library. We seem more ready to accept implicit aborts these days, such as around extern "C" functions. I think not resolving this soundness conflict is a much worse footgun.

I am not sure which team would be in charge of such a decision, but I suspect both lang and libs since this is about a decision on the safety contract of a built-in type (lang) that is best exposed via a std API (libs).
Cc @rust-lang/lang @rust-lang/libs @rust-lang/libs-api

Activity

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

    C-discussionCategory: Discussion or questions that doesn't represent real issues.I-lang-nominatedNominated for discussion during a lang team meeting.I-lang-radarItems that are on lang's radar and will need eventual work or consideration.P-lang-drag-2Lang team prioritization drag level 2.https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang.T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions