Skip to content

Can we make use of LLVM's writable for reference arguments? #584

@RalfJung

Description

@RalfJung

@nikic brought this up on Zulip before but I don't think we have an issue for this:

LLVM now has a writable attribute that allows the compiler to insert spurious writes up to the size of the dereferenceable attribute on the same pointer. It sure would be nice to use this for mutable references. OTOH, we almost certainly don't want functions like slice::as_mut_ptr to have their argument marked as "writable" -- at least if the aliasing model is anything like SB or TB, where a pointer's "derived from" identity matters until the end of the program, not just until the end of some scope (#450).

So it seems like we almost inevitably need some sort of attribute or so to control whether a function may do spurious writes to its &mut arguments. (Well, really this asks for having two types of mutable references, but I see no way that it'd actually make sense to introduce a new type here.) This would be a soundness-critical attribute (in the sense that removing the attribute can introduce UB into a program; adding it should always be fine).

That's a pretty big hammer. So far we haven't actually changed the language to experiment with SB/TB. If we add this attribute, it'll be needed in user code (e.g. ArrayVec::as_mut_ptr, SmallVec::as_mut_ptr). OTOH I don't see us stabilizing such an attribute any time soon. Crates may use cfg_attr(miri, rustc_two_phase_mutable_ref_arguments) but then we'd still add the writable attribute for normal non-Miri builds so that's not great.

The alternative would be to say, we must have a model where writable is sound for all mutable references. That kind of kills Tree Borrows. OTOH if we accept Tree Borrows as the model, that allows code which is incompatible with writable, so it's not really possible to add this back later (except with a per-function opt-in which is terrible).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions