Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last month.
Improve this question
I was wondering why Rust disallows multiple mutable borrows - even in unsafe contexts in a single threaded environment.
Let us take a small example - the unit type (). This type cannot be mutated at all, so any &mut borrow is totally equivalent to & immutable borrow.
In this example - we can have as many immutable borrows as we want, but a mutable borrow still needs exclusivity. Wouldn't it make sense to also allow multiple mutable borrows in this case?
Even in the documentation of UnsafeCell, which would allow this in unsafe context - this is defined as UB.
So why does Rust restrict borrow exclusivity in this way? Is there something I'm missing here?
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last month.
Improve this question
Lots of resources online mention how Rc<RefCell> can be used to combine multiple ownership with interior mutability. This left me wondering: why is RefCell the go-to here, rather than Cell? I'm assuming this has practical limitations, but from a purely technical perspective it can be done, e.g.:
let cell = Cell::new(5);
let rc1 = Rc::new(cell);
let rc2 = rc1.clone();
rc1.set(7);
rc2.set(9);
I imagine Cell, with its more numerous restrictions, makes it less suitable for practical applications. E.g. calling any &mut self method on the contained value. This seems particularly tricky to deal with if the contained value does not implement Copy. But this is conjecture on my part. Is there a clear reasoning for this?
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 months ago.
Improve this question
As long as there are smart pointer types in Rust, are ownership and borrowing semantics in Rust really needed? If yes, in what cases how do they used?
Yes!
Smart pointers come with quite a performance overhead. In many cases, a quick reference is all that is needed, for example if you want pass a value to a function without moving it into the function. Creating a smart pointer just for that use case would be really hurtful for performance.
Rusts primary goals are performance and safety, and that's why Rust has ownership and borrowing semantics. Otherwise there are many languages that follow the everything-is-a-smartpointer principle (actually, many of them go even one step further and use a garbage collector). It's a valid principle for memory safety, but comes with a performance hit.
Almost all languages are either memory safe or fast. Rust is unique in that sense as it tries to be both. And references/lifetimes are some of the principles that helped it to achieve that goal, at the cost of a steeper learning curve.
EDIT: Avoiding dangling pointers is just a small part of what the borrow checker can be used for. There are many more reasons to have it, like mutability, fearless concurrency, slicing, compile time ownership checks (like avoiding duplicate pin usage in embedded) and so on. How much power the borrow checker really has is probably not even completely understood yet, it was discovered that many usecases benefit from it for which it was never intended. It's just a really useful tool in general.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
If a global variable is being cloned (as implemented within the standard library) while being written to will it create a data race?
Cloning data involves reading it. Writing to data involves, well, writing it.
We can safely access data in the following ways
Any number of threads can read data at a given moment, or
One thread can write to data at a given moment, provided no one else is reading or writing
Neither of these conditions applies (we're reading for the clone and we're writing at the same time). Therefore, yes, it's a data race.
As pointed out in the comments, Rust forbids data races. You can't so much as look at a global variable in Rust without an unsafe block, since it's never safe to do so, by Rust's rules. But if you wrap your code in unsafe and don't provide additional protection then yes, this is a data race.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I'm working on a (maybe) serious programming language and want to learn about implementing memory management. I want this language to enforce RAII, similar to Rust, but, unlike rust, this language is Object-Oriented and I hope I can implement objects that manage their own memory (like Boxes in Rust). Can anyone go into detail about how Rust handles references to Heap memory?
I think the most obvious way to implement classes is:
Your class variables are implemented as pointers, like in C# and Java.
There is a single owner of the object and all class variables have move semantics in order to enforce this, like in Rust.
Memory is a resource that needs to be cleaned up, so all class variables, after calling the destructor (if any) of the referent object, also call the deallocation routine of your memory allocator, like in C++.
You introduce lifetimes in your type system in order to ensure that lending/borrowing the object doesn't allow any non-owning references to outlive it, like in Rust.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 5 years ago.
Improve this question
Rust is very actively developed and the language itself is extended regularly through the RFC process. Some of these changes, such as the Generic Associated Types RFC, have a strong impact on API-design, because new, better APIs suddenly become possible, where they weren't before.
As example, consider the mentioned GATs RFC: with this feature, we could have collection traits and could write a better version of some traits, e.g. Deref. Or take the impl Trait RFC: with that, it would be desirable to change the Iterator trait such that methods like map() would return impl Iterator instead of Map.
This is a conflict: we could improve std, but not in a backwards-compatible manner. I heard something about "Rust Epochs" (discussed here) and I think they would allow for backwards-incompatible changes.
My question is: Are there already plans on how to change the standard library's API in order to use new language features? Is a new design considered for the Rust 2019 Epoch?