Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I read somewhere that immutable and mutable borrows are perhaps alternatively understood as exclusive and shared borrows.

Yes, when it comes to exterior mutability, it's basically single mutable xor multiple immutable.

The price you pay for this convenience is run-time checking of access.

The nice thing is that RefCell is not magic, it's Rust all the way down. E.g. the status of the borrow is updated by the destructors (Drop) of the reference types. All administration is done using a signed integer to do reference counting. The value 0 means 'no borrows', any positive number indicates the number of immutable borrows, -1 means one mutable borrow.

It's well worth reading the implementation of RefCell some time!



> The nice thing is that RefCell is not magic

I'd like to point out that `RefCell` does contain a bit of magic, since it is based on `UnsafeCell`, which is _the_ core "primitive" of Rust that enables interior mutability:

https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html

(Not trying to be pedantic, just to clarify things for less knowledgeable readers).


I assume the parent meant that there was no compiler magic at play, as far as I know UnsafeCell is written in pure Rust, just using unsafe code: https://doc.rust-lang.org/src/core/cell.rs.html#1486-1488

So basically if Rust's stdlib didn't provide it, you could reimplement it yourself from scratch.

EDIT: actually, reading the comments, it looks like I'm wrong about that:

> If you have a reference `&SomeStruct`, then normally in Rust all fields of `SomeStruct` are immutable. The compiler makes optimizations based on the knowledge that `&T` is not mutably aliased or mutated, and that `&mut T` is unique. `UnsafeCell<T>` is the only core language feature to work around the restriction that `&T` may not be mutated.


WRT your edit:

  #[lang = "unsafe_cell"]
This tells you that UnsafeCell is a Language Item[1], which basically means that the compiler does have knowledge of it.

[1]: https://doc.rust-lang.org/beta/unstable-book/language-featur...


This annotation let's the compiler treat their items in special ways, but it is usually for either easier way to refer to them (I want to desugar this type to a cell of what I already have) or for diagnostics. I think box is one of the few "magical" things in the language.


I'm not sure that's correct. `UnsafeCell` is a Rust lang item that might disable some optimizations, I think?

https://doc.rust-lang.org/src/core/cell.rs.html#1483


You're right, I just saw that. Well I least I learned something new about Rust today!


Yep, you can't implement UnsafeCell yourself without running into undefined behavior.


Sorry, I should have been clearer about that. You are completely right that at some point things have to rely on some primitives that are 'magic' (in this case UnsafeCell). But I meant that RefCell itself uses standard constructs to guarantee the 'single mutable xor multiple immutable' invariant.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: