Skip to content

Commit 8eb529b

Browse files
Initial draft of copy ergonomics design note
This draws mostly on readily available links in rust-lang/rust#44619.
1 parent 70632be commit 8eb529b

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@
1010
- [Design notes](./design_notes.md)
1111
- [Allowing integer literals like `1` to be inferred to floating point](./design_notes/int_literal_as_float.md)
1212
- [Generalizing coroutines](./design_notes/general_coroutines.md)
13+
- [Copy type ergonomics](./design_notes/copy_ergonomics.md)

src/design_notes/copy_ergonomics.md

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
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

Comments
 (0)