rust


Why is std::rc::Rc<> not Copy?


Can someone explain to me why Rc<> is not Copy?
I'm writing code that uses a lot of shared pointers, and having to type .clone() all the time is getting on my nerves.
It seems to me that Rc<> should just consist of a pointer, which is a fixed size, so the type itself should be Sized and hence Copy, right?
Am I missing something?
It seems to me that Rc<> should just consist of a pointer, which is a fixed size, so the type itself should be Sized and hence Copy, right?
This is not quite true. Rc is short for Reference Counted. This means that the type keeps track of how many references point to the owned data. That way we can have multiple owners at the same time and safely free the data, once the reference count reaches 0.
But how do we keep the reference counter valid and up to date? Exactly, we have to do something whenever a new reference/owner is created and whenever a reference/owner is deleted. Specifically, we have to increase the counter in the former case and decrease it in the latter.
The counter is decreased by implementing Drop, the Rust equivalent of a destructor. This drop() function is executed whenever a variable goes out of scope -- perfect for our goal.
But when do we do the increment? You guessed it: in clone(). The Copy trait, be definition, says that a type can be duplicated just by copying bits:
Types that can be copied by simply copying bits (i.e. memcpy).
This is not true in our case, because: yes, we "just copy bits", but we also do additional work! We do need to increment our reference counter!
Drop impl of Rc
Clone impl of Rc
A type cannot implement Copy if it implements Drop (source). Since Rc does implement it to decrement its reference count, it is not possible.
In addition, Rc is not just a pointer. It consists of a Shared:
pub struct Rc<T: ?Sized> {
ptr: Shared<RcBox<T>>,
}
Which, in turn, is not only a pointer:
pub struct Shared<T: ?Sized> {
pointer: NonZero<*const T>,
_marker: PhantomData<T>,
}
PhantomData is needed to express the ownership of T:
this marker has no consequences for variance, but is necessary for
dropck to understand that we logically own a T.
For details, see:
https://github.com/rust-lang/rfcs/blob/master/text/0769-sound-generic-drop.md#phantom-data

Related Links

Borrow problems with compiled SQL statements
Conditionally derive based on feature flag
Possible to pass a '&str' or '&String' to function in Rust using 'Into'?
Why does a mutable reference to a dropped object still count as a mutable reference?
How to use 'on_send' method of Nickel response?
How to build an executable that depends on curl for x86_64-unknown-linux-musl
How can I create a struct with a HashMap where the keys the same type as the container
Issues constraining implementation lifetimes on type without lifetime parameter
How to use recursive associated types in functions?
Right way to share a reference between closures
Borrow checker and function arguments in Rust, correct or over zealous?
Most idiomatic way to create a default struct
How to return an Iterator from a Map [duplicate]
Do all primitive types implement the Copy trait?
Comparison of two floats in Rust to arbitrary level of precision
Is there a convenient way to represent x86 instructions in a struct or other language feature?

Categories

HOME
openshift
typelite
apk
nsis
tfs2015
mosquitto
visualforce
u-boot
static-analysis
tup
sharepoint-online
swarm
solution
amazon-emr
csrf
rangy
feature-extraction
multi-step
bundler
jpa-2.0
temperature
robolectric
spam
spyder
jitsi
social-tables
el
liferay-6.2
cell
firemonkey-style
raima
managed-c++
morris.js
xdebug
react-bootstrap-table
iwebbrowser2
mdns
jsonresult
phpstorm-2016.1
delayed-job
sca
nest
serversocket
apptentive
spring-rabbitmq
formsauthenticationticket
ms-dos
mv
strapi
llvm-ir
hidden-markov-models
extbase
reset
jacoco-maven-plugin
pyttsx
httphandler
moinmoin
dredd
ssi
node-apn
visual-format-language
webvtt
http-basic-authentication
alertify
gawk
raw-sockets
groovyfx
flush
ioexception
myfaces
mixins
pythonxy
hmisc
roxygen2
algebraixlib
dbmigrate
erlog
web-api
prism-4
scala-swing
tidyr
uno
zend-mail
relationships
android-2.3-gingerbread
forio-contour
sqlbindparameter
cpu-time
map
jmenubar
dynamic-rdlc-generation
spiral
server-name
kobold2d
hardcode
algol68
yuidoc
glassfish-esb
botnet
fragment-identifier
django-pagination
git-log
formal-semantics
ios-4.2
jdownloader
ninject-interception
principles
.net-client-profile
icon-language
synthesizer

Resources

Encrypt Message