Feature: Rc::clone_raw (and for Arc)

15c9a0e
Opened by Diggory Blake at 2020-12-12 00:54:55

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.

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

    Zakarum at 2020-10-19 17:31:04

  2. 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.

    ast-ral at 2020-12-12 00:33:06

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

    Mark Rousskov at 2020-12-12 00:46:57

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

    ast-ral at 2020-12-12 00:49:55