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
This example is contrived. I am familiar with how to solve this problem using traditional Rust idioms.
However, if we consider the error:
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):
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.