Why does Rust not allow the copy and drop traits on one type?

Clash Royale CLAN TAG#URR8PPP
up vote
10
down vote
favorite
From the book:
Rust wonâÂÂt let us annotate a type with the
Copytrait if the type, or any of its parts, has implemented theDroptrait. If the type needs something special to happen when the value goes out of scope and we add theCopyannotation to that type, weâÂÂll get a compile time error.
Why was the design decision made to disallow Copy and Drop on the same type?
rust traits move-semantics ownership
add a comment |Â
up vote
10
down vote
favorite
From the book:
Rust wonâÂÂt let us annotate a type with the
Copytrait if the type, or any of its parts, has implemented theDroptrait. If the type needs something special to happen when the value goes out of scope and we add theCopyannotation to that type, weâÂÂll get a compile time error.
Why was the design decision made to disallow Copy and Drop on the same type?
rust traits move-semantics ownership
This is kinda-sorta a formalization of what C++ calls the "Rule of Three".
â trentcl
Aug 7 at 14:34
add a comment |Â
up vote
10
down vote
favorite
up vote
10
down vote
favorite
From the book:
Rust wonâÂÂt let us annotate a type with the
Copytrait if the type, or any of its parts, has implemented theDroptrait. If the type needs something special to happen when the value goes out of scope and we add theCopyannotation to that type, weâÂÂll get a compile time error.
Why was the design decision made to disallow Copy and Drop on the same type?
rust traits move-semantics ownership
From the book:
Rust wonâÂÂt let us annotate a type with the
Copytrait if the type, or any of its parts, has implemented theDroptrait. If the type needs something special to happen when the value goes out of scope and we add theCopyannotation to that type, weâÂÂll get a compile time error.
Why was the design decision made to disallow Copy and Drop on the same type?
rust traits move-semantics ownership
edited Aug 6 at 9:21
Boiethios
7,86622460
7,86622460
asked Aug 6 at 9:05
sdgfsdh
6,82863375
6,82863375
This is kinda-sorta a formalization of what C++ calls the "Rule of Three".
â trentcl
Aug 7 at 14:34
add a comment |Â
This is kinda-sorta a formalization of what C++ calls the "Rule of Three".
â trentcl
Aug 7 at 14:34
This is kinda-sorta a formalization of what C++ calls the "Rule of Three".
â trentcl
Aug 7 at 14:34
This is kinda-sorta a formalization of what C++ calls the "Rule of Three".
â trentcl
Aug 7 at 14:34
add a comment |Â
2 Answers
2
active
oldest
votes
up vote
15
down vote
accepted
- The
Droptrait is used in an RAII context, typically when some resource needs to be released/closed when the object is destroyed. - In the other hand, a
Copytype is a trivial type that can be copied with amemcpyonly.
With those two descriptions, it is clearer that they are exclusive: it makes no sense to memcpy nontrivial data: what if we copy the data, and we drop one of the copies? The inner resource of the other copy will not be reliable anymore.
In fact, Copy in not even a "real" trait, in that it does not define any function. It is a special marker that says to the compiler: "you can duplicate myself with a simple bytes copy". So you cannot provide a custom implementation of Copy, because there is no implementation at all. However, you can mark a type as copyable:
impl Copy for Foo
or better, with a derive:
#[derive(Clone, Copy)]
struct Foo /* ... */
This builds only if all the fields implement Copy. Otherwise, the compiler refuses to compile because this is unsafe.
For the sake of an example, let's suppose that the File struct implements Copy. Of course, this is not the case, and this example is wrong and cannot compile:
fn drop_copy_type<T>(T x)
where
T: Copy + Drop,
// The inner file descriptor is closed there:
std::mem::drop(x);
fn main()
let mut file = File::open("foo.txt").unwrap();
drop_copy_type(file);
let mut contents = String::new();
// Oops, this is unsafe!
// We try to read an already closed file descriptor:
file.read_to_string(&mut contents).unwrap();
"With those two descriptions, it is clearer that they are exclusive" what about an implementation of a shared pointer?
â sdgfsdh
Aug 6 at 11:58
1
@sdgfsdh When you copy a shared pointer, you have to increment the inner reference counter. That's not a simplememcpy. See the drop implementation ofRcfor example.
â Boiethios
Aug 6 at 12:16
So Rust does not allow custom implementations ofCopy?
â sdgfsdh
Aug 6 at 12:34
2
@sdgfsdh Nope. Let me add more information about this in my answer.
â Boiethios
Aug 6 at 12:37
6
@sdgfsdh actually rust allows something like a custom implementation ofCopy. It is calledClone.Cloneis always explizit, can perform additional operations (such as increasing a reference count), and can coexist withDrop.
â kazemakase
Aug 6 at 13:01
add a comment |Â
up vote
4
down vote
Quoting the documentation.
[...] [A]ny type implementing
Dropcan't beCopy, because it's managing some resource besides its ownsize_of::<T>bytes.
add a comment |Â
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
15
down vote
accepted
- The
Droptrait is used in an RAII context, typically when some resource needs to be released/closed when the object is destroyed. - In the other hand, a
Copytype is a trivial type that can be copied with amemcpyonly.
With those two descriptions, it is clearer that they are exclusive: it makes no sense to memcpy nontrivial data: what if we copy the data, and we drop one of the copies? The inner resource of the other copy will not be reliable anymore.
In fact, Copy in not even a "real" trait, in that it does not define any function. It is a special marker that says to the compiler: "you can duplicate myself with a simple bytes copy". So you cannot provide a custom implementation of Copy, because there is no implementation at all. However, you can mark a type as copyable:
impl Copy for Foo
or better, with a derive:
#[derive(Clone, Copy)]
struct Foo /* ... */
This builds only if all the fields implement Copy. Otherwise, the compiler refuses to compile because this is unsafe.
For the sake of an example, let's suppose that the File struct implements Copy. Of course, this is not the case, and this example is wrong and cannot compile:
fn drop_copy_type<T>(T x)
where
T: Copy + Drop,
// The inner file descriptor is closed there:
std::mem::drop(x);
fn main()
let mut file = File::open("foo.txt").unwrap();
drop_copy_type(file);
let mut contents = String::new();
// Oops, this is unsafe!
// We try to read an already closed file descriptor:
file.read_to_string(&mut contents).unwrap();
"With those two descriptions, it is clearer that they are exclusive" what about an implementation of a shared pointer?
â sdgfsdh
Aug 6 at 11:58
1
@sdgfsdh When you copy a shared pointer, you have to increment the inner reference counter. That's not a simplememcpy. See the drop implementation ofRcfor example.
â Boiethios
Aug 6 at 12:16
So Rust does not allow custom implementations ofCopy?
â sdgfsdh
Aug 6 at 12:34
2
@sdgfsdh Nope. Let me add more information about this in my answer.
â Boiethios
Aug 6 at 12:37
6
@sdgfsdh actually rust allows something like a custom implementation ofCopy. It is calledClone.Cloneis always explizit, can perform additional operations (such as increasing a reference count), and can coexist withDrop.
â kazemakase
Aug 6 at 13:01
add a comment |Â
up vote
15
down vote
accepted
- The
Droptrait is used in an RAII context, typically when some resource needs to be released/closed when the object is destroyed. - In the other hand, a
Copytype is a trivial type that can be copied with amemcpyonly.
With those two descriptions, it is clearer that they are exclusive: it makes no sense to memcpy nontrivial data: what if we copy the data, and we drop one of the copies? The inner resource of the other copy will not be reliable anymore.
In fact, Copy in not even a "real" trait, in that it does not define any function. It is a special marker that says to the compiler: "you can duplicate myself with a simple bytes copy". So you cannot provide a custom implementation of Copy, because there is no implementation at all. However, you can mark a type as copyable:
impl Copy for Foo
or better, with a derive:
#[derive(Clone, Copy)]
struct Foo /* ... */
This builds only if all the fields implement Copy. Otherwise, the compiler refuses to compile because this is unsafe.
For the sake of an example, let's suppose that the File struct implements Copy. Of course, this is not the case, and this example is wrong and cannot compile:
fn drop_copy_type<T>(T x)
where
T: Copy + Drop,
// The inner file descriptor is closed there:
std::mem::drop(x);
fn main()
let mut file = File::open("foo.txt").unwrap();
drop_copy_type(file);
let mut contents = String::new();
// Oops, this is unsafe!
// We try to read an already closed file descriptor:
file.read_to_string(&mut contents).unwrap();
"With those two descriptions, it is clearer that they are exclusive" what about an implementation of a shared pointer?
â sdgfsdh
Aug 6 at 11:58
1
@sdgfsdh When you copy a shared pointer, you have to increment the inner reference counter. That's not a simplememcpy. See the drop implementation ofRcfor example.
â Boiethios
Aug 6 at 12:16
So Rust does not allow custom implementations ofCopy?
â sdgfsdh
Aug 6 at 12:34
2
@sdgfsdh Nope. Let me add more information about this in my answer.
â Boiethios
Aug 6 at 12:37
6
@sdgfsdh actually rust allows something like a custom implementation ofCopy. It is calledClone.Cloneis always explizit, can perform additional operations (such as increasing a reference count), and can coexist withDrop.
â kazemakase
Aug 6 at 13:01
add a comment |Â
up vote
15
down vote
accepted
up vote
15
down vote
accepted
- The
Droptrait is used in an RAII context, typically when some resource needs to be released/closed when the object is destroyed. - In the other hand, a
Copytype is a trivial type that can be copied with amemcpyonly.
With those two descriptions, it is clearer that they are exclusive: it makes no sense to memcpy nontrivial data: what if we copy the data, and we drop one of the copies? The inner resource of the other copy will not be reliable anymore.
In fact, Copy in not even a "real" trait, in that it does not define any function. It is a special marker that says to the compiler: "you can duplicate myself with a simple bytes copy". So you cannot provide a custom implementation of Copy, because there is no implementation at all. However, you can mark a type as copyable:
impl Copy for Foo
or better, with a derive:
#[derive(Clone, Copy)]
struct Foo /* ... */
This builds only if all the fields implement Copy. Otherwise, the compiler refuses to compile because this is unsafe.
For the sake of an example, let's suppose that the File struct implements Copy. Of course, this is not the case, and this example is wrong and cannot compile:
fn drop_copy_type<T>(T x)
where
T: Copy + Drop,
// The inner file descriptor is closed there:
std::mem::drop(x);
fn main()
let mut file = File::open("foo.txt").unwrap();
drop_copy_type(file);
let mut contents = String::new();
// Oops, this is unsafe!
// We try to read an already closed file descriptor:
file.read_to_string(&mut contents).unwrap();
- The
Droptrait is used in an RAII context, typically when some resource needs to be released/closed when the object is destroyed. - In the other hand, a
Copytype is a trivial type that can be copied with amemcpyonly.
With those two descriptions, it is clearer that they are exclusive: it makes no sense to memcpy nontrivial data: what if we copy the data, and we drop one of the copies? The inner resource of the other copy will not be reliable anymore.
In fact, Copy in not even a "real" trait, in that it does not define any function. It is a special marker that says to the compiler: "you can duplicate myself with a simple bytes copy". So you cannot provide a custom implementation of Copy, because there is no implementation at all. However, you can mark a type as copyable:
impl Copy for Foo
or better, with a derive:
#[derive(Clone, Copy)]
struct Foo /* ... */
This builds only if all the fields implement Copy. Otherwise, the compiler refuses to compile because this is unsafe.
For the sake of an example, let's suppose that the File struct implements Copy. Of course, this is not the case, and this example is wrong and cannot compile:
fn drop_copy_type<T>(T x)
where
T: Copy + Drop,
// The inner file descriptor is closed there:
std::mem::drop(x);
fn main()
let mut file = File::open("foo.txt").unwrap();
drop_copy_type(file);
let mut contents = String::new();
// Oops, this is unsafe!
// We try to read an already closed file descriptor:
file.read_to_string(&mut contents).unwrap();
edited Aug 6 at 12:47
answered Aug 6 at 9:14
Boiethios
7,86622460
7,86622460
"With those two descriptions, it is clearer that they are exclusive" what about an implementation of a shared pointer?
â sdgfsdh
Aug 6 at 11:58
1
@sdgfsdh When you copy a shared pointer, you have to increment the inner reference counter. That's not a simplememcpy. See the drop implementation ofRcfor example.
â Boiethios
Aug 6 at 12:16
So Rust does not allow custom implementations ofCopy?
â sdgfsdh
Aug 6 at 12:34
2
@sdgfsdh Nope. Let me add more information about this in my answer.
â Boiethios
Aug 6 at 12:37
6
@sdgfsdh actually rust allows something like a custom implementation ofCopy. It is calledClone.Cloneis always explizit, can perform additional operations (such as increasing a reference count), and can coexist withDrop.
â kazemakase
Aug 6 at 13:01
add a comment |Â
"With those two descriptions, it is clearer that they are exclusive" what about an implementation of a shared pointer?
â sdgfsdh
Aug 6 at 11:58
1
@sdgfsdh When you copy a shared pointer, you have to increment the inner reference counter. That's not a simplememcpy. See the drop implementation ofRcfor example.
â Boiethios
Aug 6 at 12:16
So Rust does not allow custom implementations ofCopy?
â sdgfsdh
Aug 6 at 12:34
2
@sdgfsdh Nope. Let me add more information about this in my answer.
â Boiethios
Aug 6 at 12:37
6
@sdgfsdh actually rust allows something like a custom implementation ofCopy. It is calledClone.Cloneis always explizit, can perform additional operations (such as increasing a reference count), and can coexist withDrop.
â kazemakase
Aug 6 at 13:01
"With those two descriptions, it is clearer that they are exclusive" what about an implementation of a shared pointer?
â sdgfsdh
Aug 6 at 11:58
"With those two descriptions, it is clearer that they are exclusive" what about an implementation of a shared pointer?
â sdgfsdh
Aug 6 at 11:58
1
1
@sdgfsdh When you copy a shared pointer, you have to increment the inner reference counter. That's not a simple
memcpy. See the drop implementation of Rc for example.â Boiethios
Aug 6 at 12:16
@sdgfsdh When you copy a shared pointer, you have to increment the inner reference counter. That's not a simple
memcpy. See the drop implementation of Rc for example.â Boiethios
Aug 6 at 12:16
So Rust does not allow custom implementations of
Copy?â sdgfsdh
Aug 6 at 12:34
So Rust does not allow custom implementations of
Copy?â sdgfsdh
Aug 6 at 12:34
2
2
@sdgfsdh Nope. Let me add more information about this in my answer.
â Boiethios
Aug 6 at 12:37
@sdgfsdh Nope. Let me add more information about this in my answer.
â Boiethios
Aug 6 at 12:37
6
6
@sdgfsdh actually rust allows something like a custom implementation of
Copy. It is called Clone. Clone is always explizit, can perform additional operations (such as increasing a reference count), and can coexist with Drop.â kazemakase
Aug 6 at 13:01
@sdgfsdh actually rust allows something like a custom implementation of
Copy. It is called Clone. Clone is always explizit, can perform additional operations (such as increasing a reference count), and can coexist with Drop.â kazemakase
Aug 6 at 13:01
add a comment |Â
up vote
4
down vote
Quoting the documentation.
[...] [A]ny type implementing
Dropcan't beCopy, because it's managing some resource besides its ownsize_of::<T>bytes.
add a comment |Â
up vote
4
down vote
Quoting the documentation.
[...] [A]ny type implementing
Dropcan't beCopy, because it's managing some resource besides its ownsize_of::<T>bytes.
add a comment |Â
up vote
4
down vote
up vote
4
down vote
Quoting the documentation.
[...] [A]ny type implementing
Dropcan't beCopy, because it's managing some resource besides its ownsize_of::<T>bytes.
Quoting the documentation.
[...] [A]ny type implementing
Dropcan't beCopy, because it's managing some resource besides its ownsize_of::<T>bytes.
answered Aug 6 at 9:16
hellow
2,1581333
2,1581333
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51704063%2fwhy-does-rust-not-allow-the-copy-and-drop-traits-on-one-type%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password

This is kinda-sorta a formalization of what C++ calls the "Rule of Three".
â trentcl
Aug 7 at 14:34