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