-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Copy: Clone has made dropck implementation unsound! #24895
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
To my mind, we should obviously fix the The remaining question is: Do we continue to have |
triage: P-high |
[breaking-change] What does this break? Basically, code that implements `Drop` and is using `T:Copy` for one of its type parameters and is relying on the Drop Check rule not applying to it. Here is an example: ```rust #![allow(dead_code,unused_variables,unused_assignments)] struct D<T:Copy>(T); impl<T:Copy> Drop for D<T> { fn drop(&mut self) { } } trait UserT { fn c(&self) { } } impl<T:Copy> UserT for T { } struct E<T:UserT>(T); impl<T:UserT> Drop for E<T> { fn drop(&mut self) { } } // This one will start breaking. fn foo() { let (d2, d1); d1 = D(34); d2 = D(&d1); } #[cfg(this_one_does_and_should_always_break)] fn bar() { let (e2, e1); e1 = E(34); e2 = E(&e1); } fn main() { foo(); } ```
dropck: Remove `Copy` from special-cased traits Fix #24895. [breaking-change] What does this break? Basically, code that implements `Drop` and is using `T:Copy` for one of its type parameters and is relying on the Drop Check rule not applying to it. Here is an example: ```rust #![allow(dead_code,unused_variables,unused_assignments)] struct D<T:Copy>(T); impl<T:Copy> Drop for D<T> { fn drop(&mut self) { } } trait UserT { fn c(&self) { } } impl<T:Copy> UserT for T { } struct E<T:UserT>(T); impl<T:UserT> Drop for E<T> { fn drop(&mut self) { } } // This one will start breaking. fn foo() { let (d2, d1); d1 = D(34); d2 = D(&d1); } #[cfg(this_one_does_and_should_always_break)] fn bar() { let (e2, e1); e1 = E(34); e2 = E(&e1); } fn main() { foo(); } ```
[breaking-change] What does this break? Basically, code that implements `Drop` and is using `T:Copy` for one of its type parameters and is relying on the Drop Check rule not applying to it. Here is an example: ```rust #![allow(dead_code,unused_variables,unused_assignments)] struct D<T:Copy>(T); impl<T:Copy> Drop for D<T> { fn drop(&mut self) { } } trait UserT { fn c(&self) { } } impl<T:Copy> UserT for T { } struct E<T:UserT>(T); impl<T:UserT> Drop for E<T> { fn drop(&mut self) { } } // This one will start breaking. fn foo() { let (d2, d1); d1 = D(34); d2 = D(&d1); } #[cfg(this_one_does_and_should_always_break)] fn bar() { let (e2, e1); e1 = E(34); e2 = E(&e1); } fn main() { foo(); } ```
Wow, that's surprising - I expected it to be illegal to have a type that is |
Sample code (playpen):
The Drop Check rule, as specified in RFC 769, requires that no methods be attached to the trait in question. The trait
Copy
used to qualify under that criteria, but with the addition of theCopy: Clone
bound, it no longer does.The original
dropck
implementation took a short-cut to enforcing the criteria (by only accepting the known builtin bounds, under the assumption that none had user-defined methods), and so now it is unsound.The text was updated successfully, but these errors were encountered: