]> git.lizzy.rs Git - rust.git/blob - src/doc/unstable-book/src/language-features/auto-traits.md
Rollup merge of #106904 - khuey:preserve_debuginfo_for_rlibs, r=davidtwco
[rust.git] / src / doc / unstable-book / src / language-features / auto-traits.md
1 # `auto_traits`
2
3 The tracking issue for this feature is [#13231]
4
5 [#13231]: https://github.com/rust-lang/rust/issues/13231
6
7 ----
8
9 The `auto_traits` feature gate allows you to define auto traits.
10
11 Auto traits, like [`Send`] or [`Sync`] in the standard library, are marker traits
12 that are automatically implemented for every type, unless the type, or a type it contains,
13 has explicitly opted out via a negative impl. (Negative impls are separately controlled
14 by the `negative_impls` feature.)
15
16 [`Send`]: ../../std/marker/trait.Send.html
17 [`Sync`]: ../../std/marker/trait.Sync.html
18
19 ```rust,ignore (partial-example)
20 impl !Trait for Type {}
21 ```
22
23 Example:
24
25 ```rust
26 #![feature(negative_impls)]
27 #![feature(auto_traits)]
28
29 auto trait Valid {}
30
31 struct True;
32 struct False;
33
34 impl !Valid for False {}
35
36 struct MaybeValid<T>(T);
37
38 fn must_be_valid<T: Valid>(_t: T) { }
39
40 fn main() {
41     // works
42     must_be_valid( MaybeValid(True) );
43
44     // compiler error - trait bound not satisfied
45     // must_be_valid( MaybeValid(False) );
46 }
47 ```
48
49 ## Automatic trait implementations
50
51 When a type is declared as an `auto trait`, we will automatically
52 create impls for every struct/enum/union, unless an explicit impl is
53 provided. These automatic impls contain a where clause for each field
54 of the form `T: AutoTrait`, where `T` is the type of the field and
55 `AutoTrait` is the auto trait in question. As an example, consider the
56 struct `List` and the auto trait `Send`:
57
58 ```rust
59 struct List<T> {
60   data: T,
61   next: Option<Box<List<T>>>,
62 }
63 ```
64
65 Presuming that there is no explicit impl of `Send` for `List`, the
66 compiler will supply an automatic impl of the form:
67
68 ```rust
69 struct List<T> {
70   data: T,
71   next: Option<Box<List<T>>>,
72 }
73
74 unsafe impl<T> Send for List<T>
75 where
76   T: Send, // from the field `data`
77   Option<Box<List<T>>>: Send, // from the field `next`
78 { }
79 ```
80
81 Explicit impls may be either positive or negative. They take the form:
82
83 ```rust,ignore (partial-example)
84 impl<...> AutoTrait for StructName<..> { }
85 impl<...> !AutoTrait for StructName<..> { }
86 ```
87
88 ## Coinduction: Auto traits permit cyclic matching
89
90 Unlike ordinary trait matching, auto traits are **coinductive**. This
91 means, in short, that cycles which occur in trait matching are
92 considered ok. As an example, consider the recursive struct `List`
93 introduced in the previous section. In attempting to determine whether
94 `List: Send`, we would wind up in a cycle: to apply the impl, we must
95 show that `Option<Box<List>>: Send`, which will in turn require
96 `Box<List>: Send` and then finally `List: Send` again. Under ordinary
97 trait matching, this cycle would be an error, but for an auto trait it
98 is considered a successful match.
99
100 ## Items
101
102 Auto traits cannot have any trait items, such as methods or associated types. This ensures that we can generate default implementations.
103
104 ## Supertraits
105
106 Auto traits cannot have supertraits. This is for soundness reasons, as the interaction of coinduction with implied bounds is difficult to reconcile.