Skip to content

Should validity of a reference depend on the *contents* of memory in any way? #414

@RalfJung

Description

@RalfJung

This is one of the successors to #77. The question is: for a reference to be valid, what (if anything) do we require about the data it points to in memory?

Note that the Rust reference currently answers this question with "things must be valid fully recursively", but in my view this is mostly because we haven't yet figured out what exactly the weaker requirement is that we actually want to impose.
This maximalist position of requiring full recursive validity is almost certainly untenable:

  • Full recursive validity is super fragile: to reason about why the reference you are creating does not cause UB, you have to reason about all code that might mutate any memory transitively reachable (via references).
  • The benefit is questionable: having deeply nested references cause UB is very unlikely to ever benefit compiler optimizations.
  • Allowing mutable references to uninit data (between consenting APIs) is (unfortunately) how the io::Read trait often works, and while better solutions are being developed, there's a long tail of copies of this API and a lot of old code to port, that we should have good reasons to consider UB.
  • For shared references with interior mutability specifically, even determining whether an &Mutex<bool> is valid would cause a conceptual data race with another thread holding the lock and mutating that bool.
  • Also see this post.
  • There is safe code violating this principle.

However, many weaker positions exist. See #346 for a broader list of arguments for why validity should not depend on the contents of memory in any way.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions