As @DanielKeep says, you can’t do this in Rust. If you have an
&mut, that means you have exclusive access to an object. If you have an
&, that means you have shared access. If someone else in another thread had an
& reference while
self.operate_something was running, the object could be in an inconsistent state and cause undefined behavior.
Furthermore, the compiler has no guarantees that
undo_something will actually put
self back in the exact same state it was left in; with an
&mut reference, you can do all kinds of things, including deallocating internal storage and reallocating it in a different place, in which case references into the original storage would be invalid and could cause undefined behavior.
Cell (which works for
Copy types, and has no runtime cost) and
RefCell (which is more general, but has run-time borrow checking overhead) in
std::sync, are necessary to add interior mutability to a type, in which you can mutate it through an
& pointer. They all avoid any undefined behavior that could occur by having multiple
&mut pointers to the same data, but all but
Cell add a runtime cost (with
RwLock being more expensive than
RefCell, as they provide cross-thread synchronization, while
RefCell does dynamic borrowing but only within a single thread).