|
| 1 | +# Copy type ergonomics |
| 2 | + |
| 3 | +## Background |
| 4 | + |
| 5 | +There are a number of pain points with `Copy` types that the lang team is |
| 6 | +interested in exploring, though active experimentation is not currently ongoing. |
| 7 | + |
| 8 | +Some key problems are: |
| 9 | + |
| 10 | +## `Copy` cannot be implemented with non-`Copy` members |
| 11 | + |
| 12 | +There are standard library types where the lack of a `Copy` impl is an |
| 13 | +active pain point, e.g., [`MaybeUninit`](https://github.com/rust-lang/rust/issues/62835) |
| 14 | +and [`UnsafeCell`](https://github.com/rust-lang/rust/issues/25053) |
| 15 | + |
| 16 | +### History |
| 17 | + |
| 18 | + * `unsafe impl Copy for T` which avoids the requirement that T is recursively |
| 19 | + Copy, but is obviously unsafe. |
| 20 | + * https://github.com/rust-lang/rust/issues/25053#issuecomment-218610508 |
| 21 | + * `Copy` is dangerous on types like `UnsafeCell` where `&UnsafeCell<T>` |
| 22 | + otherwise would not permit access to `T` in [safe |
| 23 | + code](https://github.com/rust-lang/rust/issues/25053#issuecomment-98447164). |
| 24 | + |
| 25 | +## `Copy` types can be (unintentionally) copied |
| 26 | + |
| 27 | +Even if a type is Copy (e.g., `[u8; 1024]`) it may not be a good idea to make |
| 28 | +use of that in practice, since copying large amounts of data is slow. |
| 29 | + |
| 30 | +This also comes up with `Copy` impls on `Range`, which would generally be |
| 31 | +desirable but is error-prone given the `Iterator/IntoIterator` impls on ranges. |
| 32 | + |
| 33 | +Note that "large copies" comes up with moves as well (whih are copies, just |
| 34 | +taking ownership as well), so a size-based lint is plausibly desirable for both. |
| 35 | + |
| 36 | +### History |
| 37 | + |
| 38 | +* Tracking issue: [#45683](https://github.com/rust-lang/rust/issues/45683) |
| 39 | + |
| 40 | +## References to `Copy` types |
| 41 | + |
| 42 | +Frequently when dealing with code generic over T you end up needing things like |
| 43 | +`[u8]::contains(&5)` which is ugly and annoying. Iterators of copy types also |
| 44 | +produce `&&u64` and similar constructs which can produce unexpected type errors. |
| 45 | + |
| 46 | +There is also plausibly performance left on the table with types like `&&u64`. |
| 47 | + |
| 48 | +Note that this interacts with the unintentional copies (especially of large |
| 49 | +structures). |
| 50 | + |
| 51 | +This could plausibly be done with moved values as well, so long as the |
| 52 | +semantics match the syntax (e.g. `wants_ref(foo)` acts like `wants_ref(&{foo})`) |
| 53 | +similar to how one can pass `&mut` to something that only wants `&`. |
| 54 | + |
| 55 | +### History |
| 56 | + |
| 57 | +* [RFC 2111 (not merged)](https://github.com/rust-lang/rfcs/pull/2111) |
| 58 | +* [Rust tracking issue (closed)](https://github.com/rust-lang/rust/issues/44763) |
| 59 | +* "Allow owned values where references are expected" in [rust-roadmap-2017#17](https://github.com/rust-lang/rust-roadmap-2017/issues/17) |
0 commit comments