# Relaxation of reference rules for single-threaded applications

**URL:** <https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790>\
**Category:** language design\
**Created:** [May 9, 2024, 6:06pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790 "2024-05-09T18:06:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 9, 2024, 6:06pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/1 "2024-05-09T18:06:26Z")

</div>

I want to start by admitting that I am absolutely not an expert in the field of language design. I am not even an expert at Rust.

I have a problem that I suspect could be solved by allowing the rust compiler to be configurable.

The sample code for this problem can be found here: [Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c26b2f0e950b3ae8613e301acccd6b6d)

This example is contrived. I am familiar with how to solve this problem using traditional Rust idioms.

However, if we consider the error:

```rust
error[E0499]: cannot borrow `context` as mutable more than once at a time
  --> src/main.rs:21:18
   |
20 | for bar in &mut context.bars {
   | -----------------
   | |
   | first mutable borrow occurs here
   | first borrow later used here
21 | do_thing(&mut context, &bar);
   | ^^^^^^^^^^^^ second mutable borrow occurs here

```

I wonder what problem is this error solving in this particular program? So, I run off to the Rust documentation ([References and Borrowing - The Rust Programming Language](https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html)):

> The restriction preventing multiple mutable references to the same data at the same time allows for mutation but in a very controlled fashion. It’s something that new Rustaceans struggle with because most languages let you mutate whenever you’d like. The benefit of having this restriction is that Rust can prevent data races at compile time. A _data race_ is similar to a race condition and happens when these three behaviors occur:
> 
> - Two or more pointers access the same data at the same time.
> - At least one of the pointers is being used to write to the data.
> - There’s no mechanism being used to synchronize access to the data.
> 
> Data races cause undefined behavior and can be difficult to diagnose and fix when you’re trying to track them down at runtime; Rust prevents this problem by refusing to compile code with data races!

But, where is the data race? Where is the concurrent access? I don't see one, and if we aren't solving that problem which problem are we solving? Because the limitation/solution is applied assuming the problem is there. In my application, both this contrived example and what I am developing outside of this example, I am 100% single-threaded and have no concurrency mechanisms in use whatsoever.

It occurs to me that this could be a configurable/setting on the compiler to promise that concurrency is not present, and so this use-case is fine.

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quinedot/32/7294_2.png) [@quinedot](https://internals.rust-lang.org/u/quinedot)\
**Post date:** [May 9, 2024, 6:23pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/2 "2024-05-09T18:23:36Z")

</div>

It's not just data races, it's things like iterator invalidation, non-overlapping `memcpy`, and alias-based optimizations more generally.

See also [this recent topic](https://internals.rust-lang.org/t/could-static-mut-be-made-safe-by-an-attribute-on-functions-indicating-they-are-not-called-concurrently/20250) for some conversation on how being single threaded isn't enough, even if there was an interest in creating a single-threaded Rust dialect (which there generally isn't).

---

<div class="post-metadata">

**Author:** ![quaternic](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quaternic/32/10440_2.png) [@quaternic](https://internals.rust-lang.org/u/quaternic)\
**Post date:** [May 9, 2024, 6:27pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/3 "2024-05-09T18:27:21Z")

</div>

Consider what would happen if your `do_thing` added new elements to `context.bars`, potentially reallocating it elsewhere, while the calling scope is iterating over those elements.

It's not just about concurrent modification, but also that holding a `&mut T` means that actions _not_ using that reference _won't_ access that `T`.

---

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 9, 2024, 6:30pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/4 "2024-05-09T18:30:36Z")

</div>

Yeah that's an interesting point. It makes me think I'd want a mechanism to grab an immutable reference to the collection/iterator, while being able to make mutable changes to the elements. Which seems fine, I think?

---

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 9, 2024, 6:32pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/5 "2024-05-09T18:32:10Z")

</div>

I'm not familiar enough with the problem of non-overlapping memcpy and alias-based optimizations to comment on these. I think that thread you linked is interesting though. There's definitely a case to be made for global static mutable being made safe to use in single-threaded applications though. Right now its possible using unsafe.

---

<div class="post-metadata">

**Author:** ![quaternic](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quaternic/32/10440_2.png) [@quaternic](https://internals.rust-lang.org/u/quaternic)\
**Post date:** [May 9, 2024, 6:45pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/6 "2024-05-09T18:45:31Z")

</div>

Maybe you're looking for [Cell](https://doc.rust-lang.org/std/cell/index.html#cellt), which allows mutation through shared references, by disallowing sharing across threads.

---

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 9, 2024, 6:49pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/7 "2024-05-09T18:49:03Z")

</div>

Hmm. I don't think so? Having just now read some of the docs on Cell, it looks like it operates dominantly off of copying. The I'd definitely want mutable access to the value it holds and not copy values around, if possible. I've read some about RefCell, but if I'm understanding properly it moves the problem into runtime and panics there instead of having a compiler error. Maybe I am misunderstanding the usage of these though.

---

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 9, 2024, 7:32pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/8 "2024-05-09T19:32:45Z")

</div>

It's really like I want a MutVec where I can pass a immutable reference to MutVec such that what the list contains isn't mutable, but the elements in the list are each individually mutable.

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [May 9, 2024, 8:14pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/9 "2024-05-09T20:14:55Z")

</div>

[`.iter_mut()`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.iter_mut) or [`.as_mut_slice()`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.as_mut_slice)?

---

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 9, 2024, 8:24pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/10 "2024-05-09T20:24:49Z")

</div>

Doesn't this require a mutable reference to the thing you're calling iter\_mut() on?

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [May 10, 2024, 1:15am UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/11 "2024-05-10T01:15:21Z")

</div>

It gives you an immutable "container" with mutable access to the elements. `.as_mut_slice()` works too and can also give an iterator. Do you also want something else to hold write access to the container part? I'm not sure what one can do with such a view on a container though…`.shrink_to_fit()`? `.try_reserve()`?

I suspect some GhostToken-like permission split mechanism could work here, but without the power to reallocate, I'm not sure what the separate container access is supposed to achieve.

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skifire13/32/7579_2.png) [@SkiFire13](https://internals.rust-lang.org/u/SkiFire13)\
**Post date:** [May 10, 2024, 4:52am UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/12 "2024-05-10T04:52:16Z")

</div>

The problem with this is that you would still be able to get shared references to the items from the original collection, then the mutable references yielded by the iterator would allow you to invalidate them.

```rust
let foo: Vec<Vec<Something>> = ...;
let first: &Something = &foo[0][0];
// Pretent this somehow yields &mut references
for mut_ref in &foo {
    mut_ref.clear();
}
// first now points to invalid memory, so this is bad
println!("{first}"});

```

Also mandatory (IMO) read: [The Problem With Single-threaded Shared Mutability - In Pursuit of Laziness](https://manishearth.github.io/blog/2015/05/17/the-problem-with-shared-mutability/)

---

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 10, 2024, 6:31pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/13 "2024-05-10T18:31:59Z")

</div>

Ok, that was an excellent article. It makes me think we should be able to attach qualifiers to the references we take. The ability so say something like:

- Reference-A cannot be equal to Reference-B.
- Take a reference to a Vec that allows mutability of the existing elements, but not the length of the list.

So, some kind of semantics that establish qualifications on the references you take, as well as providing those qualifiers via an API for collections like Vec, so that Vec can write conditionally unsafe code.

Edit: the purpose of such features would be to keep the checks at compile time instead of just deferring checks to runtime via RefCell and friends.

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skifire13/32/7579_2.png) [@SkiFire13](https://internals.rust-lang.org/u/SkiFire13)\
**Post date:** [May 10, 2024, 9:10pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/14 "2024-05-10T21:10:07Z")

</div>

I'm not so sure about what you're proposing. For example:

> [@ObeyMinute](#):
>
> Take a reference to a Vec that allows mutability of the existing elements, but not the length of the list.

This is just a `&mut [T]`, which you can already get from a `Vec`.

* * *

How would those qualifications look in practice? What would they allow that's new? And how would the compiler check for them?

---

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 10, 2024, 10:33pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/15 "2024-05-10T22:33:44Z")

</div>

I don't know that I have a ton to offer here, at least not much more than misunderstandings of the issue and ramblings on how I think it might be addressed. To the extent that I have any ideas I'll try for guess at what I might do if I was actually in the position of knowing what to do and being capable fo doing it in terms of applying changes to Rust.

```rust
struct Foo {
    pub value_1: u32,
    pub value_2: u32,
    pub value_3: u32,
}

fn main() {
    let mut foo = Foo {
        value_1: 1,
        value_2: 2,
        value_3: 3,
    };

    let v1 = &mut foo.value_1;

    do_thing(&mut foo, v1);

    *v1 *= 5;
}

fn do_thing(f: &mut Foo, u: &mut u32) {
    f.value_2 = 10;
    f.value_3 = 10;
    *u *= 2;
}

```

The above code does not compile, even though there is actually nothing wrong with the program. The compiler is clear about why:

```rust
error[E0499]: cannot borrow `foo` as mutable more than once at a time
  --> src/main.rs:21:14
   |
19 | let v1 = &mut foo.value_1;
   | ---------------- first mutable borrow occurs here
20 |
21 | do_thing(&mut foo, v1);
   | ^^^^^^^^ -- first borrow later used here
   | |
   | second mutable borrow occurs here

For more information about this error, try `rustc --explain E0499`.

```

However, it seems odd because it seems like it could be detectable that we are mutating foo in a way that doesn't violate memory safety, right? It's not like in "do\_thing" the alias for "f.value\_1" and alias for "u" are actually in conflict. Is my understanding of this right? Am I missing something here?

So, this type of thing seems detectable (again not an expert in this whole langauge design business). And in a similiar aesthetic and even technical mechanism for how lifetimes can be written and elided when their usage is obvious, we could have similar markup to denote the precise accesses a reference can have.

So we could write something like:

```rust
fn do_thing(f: &'a @[value_2, value_3] mut Foo, u: &'a mut u32) {
    f.value_2 = 10;
    f.value_3 = 10;
    *u *= 2;
}

```

Ignore the syntax ugliness. The idea is to convey that the first reference only intends to modify value\_2 and value\_3. The function should then only be able to modify value\_2 and value\_3 through that alias. And then it doesn't matter what is passed into the alias "u" because the compiler knows that whatever reference is aliased as "u" must not be in conflict with "f".

I also realize I could have written this another way:

```rust
struct Foo {
    pub value_1: u32,
    pub value_2: u32,
    pub value_3: u32,
}

fn main() {
    let mut foo = Foo {
        value_1: 1,
        value_2: 2,
        value_3: 3,
    };

    let v1 = &mut foo.value_1;
    let v2 = &mut foo.value_2;
    let v3 = &mut foo.value_3;

    do_thing(v1, v2, v3);

    *v1 *= 5;
}

fn do_thing(v1: &mut u32, v2: &mut u32, v3: &mut u32,) {
    *v2 = 10;
    *v3 = 10;
    *v1 *= 2;
}

```

However that gets tedious as the application gets larger. There's a desire I have heard repeated by a lot of new-to-Rust devs where it's desirable to pass around a context object of some kind instead of having to split the context up into itty-bitty-pieces and pass each of its fields in as an individual reference. This would help there. Although you could just get tired of the tedium of writting out @[value\_2, value\_3] as well. Which would be a far complaint. But we could bundle these into some kind of reference-aspect that a type provides.

```rust
impl Foo {
    pub @some_name_here = [value_1, value_2] 
}

...

fn do_thing(f: &'a @some_name_here mut Foo, u: &'a mut u32) {
    f.value_2 = 10;
    f.value_3 = 10;
    *u *= 2;
}

```

I'm not sure I'm making sense, or maybe I am making sense but I might just lack a ton of knowledge that would make it obvious to me how wrong this suggestion is.

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skifire13/32/7579_2.png) [@SkiFire13](https://internals.rust-lang.org/u/SkiFire13)\
**Post date:** [May 11, 2024, 7:38am UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/16 "2024-05-11T07:38:33Z")

</div>

This is generally called "partial borrows". There was a topic just a couple days ago on experimenting on them [Idea: Experimental attribute based support for partial borrows](https://internals.rust-lang.org/t/idea-experimental-attribute-based-support-for-partial-borrows/20744)

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [May 11, 2024, 12:28pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/17 "2024-05-11T12:28:44Z")

</div>

You can have mutable aliasing on a single thread already if you use the `&Cell` type. See `as_slice_of_cells`

> **[Cell in std::cell - Rust](https://doc.rust-lang.org/std/cell/struct.Cell.html#method.as_slice_of_cells)**
>
> A mutable memory location.

---

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 11, 2024, 5:33pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/18 "2024-05-11T17:33:47Z")

</div>

Cell requires copying and for my case that's unfortunately a non-starter.

---

<div class="post-metadata">

**Author:** ![ObeyMinute](https://avatars.discourse-cdn.com/v4/letter/o/8e7dd6/32.png) [@ObeyMinute](https://internals.rust-lang.org/u/ObeyMinute)\
**Post date:** [May 11, 2024, 5:37pm UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/19 "2024-05-11T17:37:34Z")

</div>

Yeah, so something like this or adjacent to it is what I am looking for. I'm not trying to be particularly prescriptive with the syntax, just the desire for some kind of split/partial borrowing that has better compile time support and also a desire for more expressive syntax to help with disambiguating the things the compiler might struggle to sort out.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [May 12, 2024, 1:04am UTC](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790/20 "2024-05-12T01:04:10Z")

</div>

No, this doesn't require copying. It's possible to cast `&mut [u8]` to `&[Cell<u8>]` at no cost, without copying. `cell[x].set(val)` is the same thing as `slice[x] = val`, except noalias guarantees.

[Next page](https://internals.rust-lang.org/t/relaxation-of-reference-rules-for-single-threaded-applications/20790.md?page=2)
