3 ms·
You cannot turn a &T into a Box<T>, because &T borrows T, while Box<T> owns T, and moreover it holds it in a separate allocation, so even &mut T cannot be trans
by yakubin 5y ago
You cannot turn a &T into a Box<T>, because &T borrows T, while Box<T> owns T, and moreover it holds it in a separate allocation, so even &mut T cannot be transformed into Box<T> --- it already lives in some allocated space and whatever there is a reference to, cannot be moved to a new allocation. For moving T you need T, not a reference to T. The case with UnsafeCell<T> substituted in place of T is just a special case.
UnsafeCell<T> also owns T, so transforming &mut T into UnsafeCell<T> also doesn't make sense. The unsafe equivalent of references is pointers.
- nyanpasu64 5y agoC++ lets you easily delete a T* or T const*, Rust has https://doc.rust-lang.org/std/primitive.pointer.html#2-consume-a-box-boxt https://doc.rust-lang.org/std/primitive.pointer.html#2-consu... I guess? > UnsafeCell<T> also owns T, so transforming &mut T into UnsafeCell<T> also doesn't make sense. I wanted to transform a &mut T into &UnsafeCell<T> (note the &) and copy the reference, to allow shared mutation scoped within the lifetime of the source &mut T. How can this be accomplished?
- yakubin 5y ago> C++ lets you easily delete a T* or T const*, Rust has https://doc.rust-lang.org/std/primitive.pointer.html#2-consu https://doc.rust-lang.org/std/primitive.pointer.html#2-consu... I guess? Box deletes the owned object when it goes out of scope without being moved (like unique_ptr in C++). So if anything, you want to go the other way: https://doc.rust-lang.org/std/boxed/struct.Box.html#method.from_raw https://doc.rust-lang.org/std/boxed/struct.Box.html#method.f... However, you can delete a *T by using <https://doc.rust-lang.org/std/alloc/trait.Allocator.html#tymethod.deallocate https://doc.rust-lang.org/std/alloc/trait.Allocator.html#tym...> with the Global allocator (since this is the one you're most likely using). > I wanted to transform a &mut T into &UnsafeCell<T> (note the &) and copy the reference, to allow shared mutation scoped within the lifetime of the source &mut T. How can this be accomplished? If you want to have two instances of one &mut T, you don't go through &UnsafeCell<T>. Instead you may cast &mut T into *mut T and then use this: <https://doc.rust-lang.org/std/primitive.pointer.html#method.as_mut-1 https://doc.rust-lang.org/std/primitive.pointer.html#method....>. This however will cast into any lifetime, so if you want to bind the two lifetimes together, then you need to have the lifetime of the original &mut T explicitly specified, and then you assign the result of the method I linked to a variable with explicitly specified type where you specify the lifetime annotation. Alternatively, you may write a separate function which accepts both references as arguments and binds the two lifetimes together the usual way. I admit it's a bit unergonomic. The best way currently would be to have the data stored as UnsafeCell in the first place and then call get_mut() on it to get all the references. However, if this reference comes from outside, you're left with the little mess I outlined above.