Mutable aliasing is when we hold two mutable references to the same data. This can become a problem.

    std::vector<T> vec;
    auto & item = vec;

    for (auto & x : vec) {
        do_stuff(item);
    }

The problem here is that do_stuff can mutate the vector and thus invalidate the iterator, causing undefined behavior.

Some languages just avoid mutable state altogether (or mostly). Rust simply checks that there is no mutable aliasing at compile time. If that's not possible then this can be done dynamically (at a cost using RefCell).

Not only can mutable aliasing cause undefined behavior in some programs, it can also cause logical errors. If your code holds some mutable reference and assumes that some invariant is upheld due to its own usage, another piece of code may break that invariant.

RefCell

Rust has a type in its standard library std::cell::RefCell that dynamically checks whether its content isn't already mutably being accessed. This allows us to do safe (as in memory-safe) mutable aliasing, however, it can still lead to panics if we do have two mutable accesses. That's not good, since it can cause crashes in untested code paths. It is ideal to use RefCell only as a workaround to the type system when we know that mutable aliasing cannot occur but we need shared memory.