]> git.lizzy.rs Git - rust.git/blob - src/doc/style/features/traits/common.md
Changed issue number to 36105
[rust.git] / src / doc / style / features / traits / common.md
1 % Common traits
2
3 ### Eagerly implement common traits. [FIXME: needs RFC]
4
5 Rust's trait system does not allow _orphans_: roughly, every `impl` must live
6 either in the crate that defines the trait or the implementing
7 type. Consequently, crates that define new types should eagerly implement all
8 applicable, common traits.
9
10 To see why, consider the following situation:
11
12 * Crate `std` defines trait `Debug`.
13 * Crate `url` defines type `Url`, without implementing `Debug`.
14 * Crate `webapp` imports from both `std` and `url`,
15
16 There is no way for `webapp` to add `Debug` to `url`, since it defines neither.
17 (Note: the newtype pattern can provide an efficient, but inconvenient
18 workaround; see [newtype for views](../types/newtype.md))
19
20 The most important common traits to implement from `std` are:
21
22 ```text
23 Clone, Debug, Hash, Eq
24 ```
25
26 #### When safe, derive or otherwise implement `Send` and `Share`. [FIXME]
27
28 > **[FIXME]**. This guideline is in flux while the "opt-in" nature of
29 > built-in traits is being decided. See https://github.com/rust-lang/rfcs/pull/127
30
31 ### Prefer to derive, rather than implement. [FIXME: needs RFC]
32
33 Deriving saves implementation effort, makes correctness trivial, and
34 automatically adapts to upstream changes.
35
36 ### Do not overload operators in surprising ways. [FIXME: needs RFC]
37
38 Operators with built in syntax (`*`, `|`, and so on) can be provided for a type
39 by implementing the traits in `core::ops`. These operators come with strong
40 expectations: implement `Mul` only for an operation that bears some resemblance
41 to multiplication (and shares the expected properties, e.g. associativity), and
42 so on for the other traits.
43
44 ### The `Drop` trait
45
46 The `Drop` trait is treated specially by the compiler as a way of
47 associating destructors with types. See
48 [the section on destructors](../../ownership/destructors.md) for
49 guidance.
50
51 ### The `Deref`/`DerefMut` traits
52
53 #### Use `Deref`/`DerefMut` only for smart pointers. [FIXME: needs RFC]
54
55 The `Deref` traits are used implicitly by the compiler in many circumstances,
56 and interact with method resolution. The relevant rules are designed
57 specifically to accommodate smart pointers, and so the traits should be used
58 only for that purpose.
59
60 #### Do not fail within a `Deref`/`DerefMut` implementation. [FIXME: needs RFC]
61
62 Because the `Deref` traits are invoked implicitly by the compiler in sometimes
63 subtle ways, failure during dereferencing can be extremely confusing. If a
64 dereference might not succeed, target the `Deref` trait as a `Result` or
65 `Option` type instead.
66
67 #### Avoid inherent methods when implementing `Deref`/`DerefMut` [FIXME: needs RFC]
68
69 The rules around method resolution and `Deref` are in flux, but inherent methods
70 on a type implementing `Deref` are likely to shadow any methods of the referent
71 with the same name.