# Canvas unsafe code in the wild

**URL:** <https://internals.rust-lang.org/t/canvas-unsafe-code-in-the-wild/4990>\
**Category:** Unsafe Code Guidelines\
**Created:** [March 23, 2017, 1:58pm UTC](https://internals.rust-lang.org/t/canvas-unsafe-code-in-the-wild/4990 "2017-03-23T13:58:10Z")\
**Posts on this page:** 1\
**Showing post:** 16

<div class="post-metadata">

**Author:** ![RalfJung](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ralfjung/32/2415_2.png) [@RalfJung](https://internals.rust-lang.org/u/RalfJung)\
**Post date:** [June 12, 2017, 11:25pm UTC](https://internals.rust-lang.org/t/canvas-unsafe-code-in-the-wild/4990/16 "2017-06-12T23:25:26Z")

</div>

Okay so I had a closer look at `Rc`. I know I got assigned `Arc`, but I am more familiar with `Rc` because I looked _very_ closely at it as part of the [RustBelt research project](http://plv.mpi-sws.org/rustbelt/).

Mostly, in terms of what we are discussing as part of the unsafe code guidelines, `Rc` seems to be fairly harmless. Here’s what I found noteworthy. There’s nothing big, I just felt I couldn’t come back without anything to report 😉

### Struct field offsets

`into_raw` and `from_raw` do some pointer arithmetic based on offsets of struct fields, I think there is general agreement that this should be possible. The concrete implementation of this in the `offset_of!` macro uses `mem::uninitialized()` and then calls `mem::forget()` in the result. This means `mem::forget` can get called with a totally invalid argument, but that’s not too surprising – in fact, this is even suggested by the official documentation of `mem::foget()`. I was a little surprised that the offset is in fact computed at run-time; you would think that the field offset is a compile-time constant.

### ` __from_str`, `__ from_array`

These are super-dubious, as even the comments in there say. If I read the code correctly, they assume that a fat pointer can be created by creatively casting a two-element array… However, they are private to rustc.

### `RcBoxPtr`

`Rc::drop` calls `RcBoxPtr::dec_weak` _after_ decrementing the strong count and droping the content of the `RcBox`. This is somewhat interesting because `RcBoxPtr::dec_weak` takes `&Rc<T>` as an argument and is a perfectly safe function, but it is actually called on an `Rc` that is in a bad state – it doesn’t satisfy the usual invariants that `Rc` typically satisfies. However, the `Rc` passed to `dec_weak` is still a valid instance of a "syntactic `Rc`", so I don’t think the compiler could exploit this in any way.

---

_[View the full topic](https://internals.rust-lang.org/t/canvas-unsafe-code-in-the-wild/4990)._
