rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
97.31k stars 12.58k forks source link

Feature: `Rc::clone_raw` (and for Arc) #48108

Open Diggsey opened 6 years ago

Diggsey commented 6 years ago

When using from_raw/into_raw functions with Rc, you often want to obtain a new reference to a raw pointer, without taking ownership. At the moment you have to do this dance:

fn clone_raw<T>(ptr: *const T) -> Rc<T> {
    let result = unsafe { Rc::from_raw(ptr) };
    ::std::mem::forget(result.clone());
    result
}

This is quite error prone and makes little sense to anyone trying to read the code. It would be better if the standard library had clone_raw built in for Rc and Arc, and possibly for their weak variants.

zakarumych commented 3 years ago

This looks like a simple and useful feature, but seems forgotten.

ast-ral commented 3 years ago

I think a potentially easy solution to this is to just have a function to increment the strong count directly from the pointer, and then have the user make two Rcs from it later, using Rc::from_raw. The current code to increment the strong count on a raw Rc ptr is:

unsafe fn increment_count<T>(ptr: *const T) {
    let rc = Rc::from_raw(ptr);
    std::mem::forget(rc.clone());
    std::mem::forget(rc);
}

Which seems a bit silly to just increment one value.

Mark-Simulacrum commented 3 years ago

https://github.com/rust-lang/rust/pull/79285 stabilizes the increment/decrement operators.

ast-ral commented 3 years ago

That unfortunately only seems to apply to Arc. (Edit: Upon further review, Rc is mentioned as a follow-up change, sorry to bother.)