Skip to content

What's the source of immutability for pointers produced by const? #502

Open
@RalfJung

Description

@RalfJung

If a const (item or expression) contains references and pointers, then what is their mutability (or more generally, their status in the aliasing model)?

It seems fairly clear that we want them to be immutable. It's called "const(ant)" after all, and also constants are values but we deduplicate the underlying storage, which would be bad news if anything is mutable.

Currently we're doing our best to make this an implementation detail: const-eval tracks the actual mutability of a pointer, and interning bails out if a mutable pointer makes it into the final value. That means all the pointers in the final value are anyway already immutable.

But there's an alternative: we can say that the transition from a const result to a value embedded in other computations (that may themselves be const computations, or they may happen at runtime) makes all pointers (or, equivalently, the memory they point to) immutable.

This has several advantages:

It also has several downsides:

  • We have a second source of immutability constraints, aside from shared references. So if people don't expect that they may cause UB. (A mitigating factor here is that writing to the memory that contains a const should segfault pretty reliably on most targets, as that memory is typically mapped read-only. So this UB will often be detected.)
  • The check we'd have to remove was meant as a safety net for &mut values in consts. If an &mut value ends up in the result of a const, the new rules would say that despite it being a mutable reference, it actually is an immutable pointer. We can catch some cases where that happens, but if people get creative and e.g. smuggle out an &mut inside a MaybeUninit, there's a chance to cause UB.

The downsides are why I added these checks in the first place, and they make me hesitant to un-do all that work. OTOH I did not see #493 coming, and it's undeniably useful to be able to do const { &None } even when this is an Option<Cell<T>>.

Cc @rust-lang/wg-const-eval, this issue is an the intersection of opsem and const-eval.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-aliasing-modelTopic: Related to the aliasing model (e.g. Stacked/Tree Borrows)

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions