Skip to content

Backwards compatibility hazard with Box + &mut behaviour that cannot be replicated by a pure-library type #14270

Closed
@huonw

Description

@huonw

With Box built deeply into the compiler, one can currently write

let mut y = 1;
let x: Box<&mut int> = box &mut y;
**x = 2;

That is, one can mutate through a &mut stored in the Box, even if the Box itself is not in a mutable slot. This is (presumably) because the compiler currently understands a lot about Boxs behaviour, in particular, that it can act like an immutable unaliased pointer (&uniq).

There's currently no way to get this behaviour for library types, e.g. Vec<&mut int> is theoretically identical to Box in terms of ownership/aliasability of its contents, but, as it is a library type, the following cannot be made to work:

let mut y = 1;
let x: Vec<&mut int> = vec![&mut y];
// error: can't mutate a `& &mut int`
**x.get(0) = 2;
// error: can't borrow x as mutable
**x.get_mut(0) = 2;

We would need an immutable &uniq pointer for this behaviour to be possible for general simply-owned types like an in-library Box, Vec, HashMap etc.

Having this behaviour for Box represents a possible backwards compatibility hazard if we ever decide to move Box more into libraries. Specifically, moving Box into a library and preserving its current behaviour perfectly would require (at least) adding this new &uniq pointer type.

(Thanks to /u/SteveMcQwark on reddit for prompting this.)

(Nominating.)

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions