From 7edc64590e49ba8f277ac21fa4b38c59c8412d77 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 20 Oct 2020 12:32:20 -0400 Subject: [PATCH] Initial draft of copy ergonomics design note This draws mostly on readily available links in https://github.com/rust-lang/rust/issues/44619. --- src/design_notes/copy_ergonomics.md | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/design_notes/copy_ergonomics.md diff --git a/src/design_notes/copy_ergonomics.md b/src/design_notes/copy_ergonomics.md new file mode 100644 index 0000000..0e3cba2 --- /dev/null +++ b/src/design_notes/copy_ergonomics.md @@ -0,0 +1,54 @@ +# Copy type ergonomics + +## Background + +There are a number of pain points with `Copy` types that the lang team is +interested in exploring, though active experimentation is not currently ongoing. + +Some key problems are: + +## `Copy` cannot be implemented with non-`Copy` members + +There are standard library types where the lack of a `Copy` impl is an +active pain point, e.g., [`MaybeUninit`](https://github.com/rust-lang/rust/issues/62835) +and [`UnsafeCell`](https://github.com/rust-lang/rust/issues/25053) + +### History + + * `unsafe impl Copy for T` which avoids the requirement that T is recursively + Copy, but is obviously unsafe. + * https://github.com/rust-lang/rust/issues/25053#issuecomment-218610508 + * `Copy` is dangerous on types like `UnsafeCell` where `&UnsafeCell` + otherwise would not permit access to `T` in [safe + code](https://github.com/rust-lang/rust/issues/25053#issuecomment-98447164). + +## `Copy` types can be (unintentionally) copied + +Even if a type is Copy (e.g., `[u8; 1024]`) it may not be a good idea to make +use of that in practice, since copying large amounts of data is slow. + +This also comes up with `Copy` impls on `Range`, which would generally be +desirable but is error-prone given the `Iterator/IntoIterator` impls on ranges. + +Note that "large copies" comes up with moves as well (whih are copies, just +taking ownership as well), so a size-based lint is plausibly desirable for both. + +### History + +* Tracking issue: [#45683](https://github.com/rust-lang/rust/issues/45683) + +## References to `Copy` types + +Frequently when dealing with code generic over T you end up needing things like +`[u8]::contains(&5)` which is ugly and annoying. Iterators of copy types also +produce `&&u64` and similar constructs which can produce unexpected type errors. + +There is also plausibly performance left on the table with types like `&&u64`. + +Note that this interacts with the unintentional copies (especially of large +structures). + +### History + +* [RFC 2111 (not merged)](https://github.com/rust-lang/rfcs/pull/2111) +* [Rust tracking issue (closed)](https://github.com/rust-lang/rust/issues/44763)