# Rc and internal mutability

**URL:** <https://internals.rust-lang.org/t/rc-and-internal-mutability/11463>\
**Category:** libs\
**Created:** [December 10, 2019, 5:56pm UTC](https://internals.rust-lang.org/t/rc-and-internal-mutability/11463 "2019-12-10T17:56:07Z")\
**Posts on this page:** 1\
**Showing post:** 11

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [December 14, 2019, 8:11pm UTC](https://internals.rust-lang.org/t/rc-and-internal-mutability/11463/11 "2019-12-14T20:11:27Z")

</div>

Does this mean that my [(`A`)`RcBorrow::upgrade`](https://cad97.github.io/rowan/rc_borrow/struct.ArcBorrow.html#method.upgrade) is unsound? It's a not _too_ uncommon pattern to allow upgrading from `&T` where the `T` is statically known to be behind an (`A`)`Rc` to an (`A`)`Rc<T>`, and that's what that library is providing a type for.

The implementation currently uses

```rust
pub struct $RcBorrow<'a, T: ?Sized> {
    raw: ptr::NonNull<T>,
    marker: PhantomData<&'a $Rc<T>>
}

impl<'a, T: ?Sized> From<&'a $Rc<T>> for $RcBorrow<'a, T> {
     fn from(v: &'a $Rc<T>) -> $RcBorrow<'a, T> {
        $RcBorrow {
            raw: (&**v).into(),
            marker: PhantomData,
        }
    }
}

impl<'a, T: ?Sized> $RcBorrow<'a, T> {
    /// Convert this borrowed pointer into an owned pointer.
    pub fn upgrade(this: Self) -> $Rc<T> {
        unsafe { $Rc::clone(&ManuallyDrop::new($Rc::from_raw(this.raw.as_ptr()))) }
    }

    /// Convert this borrowed pointer into a standard reference.
    pub fn downgrade(this: Self) -> &'a T {
        unsafe { &*this.raw.as_ptr() }
    }
}

```

As I understand it, we've determined that this way of implementing `into_raw` is incorrect when using the current Stacked Borrows rules, so my "`as_raw`" implementation would also be unsound to turn into a `&$Rc<T>` to clone, as it's lost write provenance over the location of `T`. (And a unique `$Rc<T>` can be used to write.)

If I understand correctly, the way to make this sound would be to

- Provide a `$Rc::<T>::as_raw(&self) -> *const T` function that uses pointer manipulation instead of `Deref`,
- Use that in the implementation of `$RcBorrow<'_, T>`, and
- Say that the implicit case of `&T` -\> `$Rc<T>` where `T` is known statically to only be allocated behind `$Rc` is actually unsound (unsafe when used to write).

I'm ok with that for this library, but I know `&T` -\> `$Rc<T>` is used in the wild.

---

_[View the full topic](https://internals.rust-lang.org/t/rc-and-internal-mutability/11463)._
