Plain referencing and cloning an Rc object points to the same allocation of the original data or owner. They do not clone the data. However in the case of plain immutable reference it is known as borrowing, but in cloning Rc object it is known as shared ownership. Why?
I think I am having difficulty understanding sharing ownership. My understanding is that each piece of data in Rust has a single owner, the data can be shared by borrowing or cloning, and ownership can be transferred by moving the data, but sharing ownership? That seems a bit harsh on the ownership model. It seems to me that sharing ownership is another name for borrowing.
ownership (shared or unique) is for resource management, borrowing (shared or exclusive) is for access control.
ownership is how rust gets rid of GC, access is how rust gets rid of data races.
rust's "no safe (unsynced) shared mutability" model is about access rights, not about ownerships.
who owns the value determines where the destructor (Drop) is run. for unique ownerships, it's statically known. for shared ownerships, it depends on runtime behaviors.
ownerships derives the access right you can have. for example, when you hold a unique ownership of some value, you automatically gains the shared and exclusive access right (explicitly borrow or implicitly ref-coercion for self); but if you only have a shared ownership, you don't necessarily automatically get the exclusive access right: you must do runtime checks.
Rc<T> is shared ownership, because it is a pointer to an instance of T allocated on the heap. Basically, we put on the heap (usize, T), where usize is the reference counter. We guarantee that the value of the reference count is precisely equal to the number of Rc<T> instances pointing to this allocation. When you clone an Rc<T>, the corresponding reference count is incremented by 1. When you drop it, the reference counter is decremented by 1. When the last instance is dropped, the reference count becomes equal to 0, so we also deallocate (usize, T).
A reference &T or &mut T does no such things, and doesn't create any new memory allocations. It's just a pointer to an existing instance of T, together with certain liveness and aliasing guarantees which enable us to unconditionally dereference &T/&mut T for as long as it exists. This means that the pointer itself cannot outlive the pointed to instance of T, which is precisely what the borrow checker tracks.
Note that Rc<T> is not in any way magic and doesn't violate Rust's usual ownership semantics. Each individual instance of Rc<T> behaves as usual: it is an owned value which can be temporarily borrowed or moved between scopes, and when the value finally goes out of scope, it is dropped. It is the impl Drop for Rc<T> where the magic happens: we have unsafe code which performs the reference count dance described above. This means that clones of an Rc<T> represent shared ownership of T, while each individual Rc<T> is owned in the normal way.
Rust's Rc is just the usual meaning of traditional reference counting. It implements a pointer-like type that keeps the pointed object alive as long as there is at least one pointer pointing to the object. The last pointer to be dropped will also deallocate and drop the pointed object. This is achieved via dynamic memory management ("heap allocation" if you wish).
It is not. A built-in primitive reference does not keep its referent alive. When you use a primitive reference, you must ensure, by means of appropriate scoping of the binding that owns the value, that the referent is kept alive as long as there are references to it. In contrast, Rcmakes sure for you that as long as an Rc exists, its referent is valid – but this comes at a price, because this dynamic scoping requires a heap allocation.
This is precisely why Rc implements the idea of shared ownership – the ability to prolongate or dictate the lifetime of a value. Borrowing does not do that.
Do you understand how shared ownership works in real life? Like in example: me and four my relatives own an appartment. Do you understand how that works? What happen if one of guys who lives in the apartment get a divorce or, maybe, produces an offspring? List of owners is altered and where we have six or four owners instead of five (usually money are also involved, but that's next level). And when final owner leaves the apartment because house is too decrepit… it's destroyed.
That whole discussion about Rust's ownership and borrow system always leaves me baffled: it really sounds as if people are struggling with something that shouldn't be a problem at all, with something that happens to normal layman quite often, where you should just think about how entites are handled and used in the big world outside of computers… and yet people couldn't do that… but why? Why there's even trouble at all?
Note: I'm not saying it's always easy to understand all the rules of the borrow checkers, these could be pretty complicated and involved[1], but the core idea… ownership and borrow system from non-IT world just quite literally maps on top of Rust's borrow system (and it even includes some cases which not [yet] possible in Rust)!