1
//! The `Default` trait for types with a default value.
2

            
3
#![stable(feature = "rust1", since = "1.0.0")]
4

            
5
#[cfg(not(feature = "ferrocene_certified"))]
6
use crate::ascii::Char as AsciiChar;
7

            
8
/// A trait for giving a type a useful default value.
9
///
10
/// Sometimes, you want to fall back to some kind of default value, and
11
/// don't particularly care what it is. This comes up often with `struct`s
12
/// that define a set of options:
13
///
14
/// ```
15
/// # #[allow(dead_code)]
16
/// struct SomeOptions {
17
///     foo: i32,
18
///     bar: f32,
19
/// }
20
/// ```
21
///
22
/// How can we define some default values? You can use `Default`:
23
///
24
/// ```
25
/// # #[allow(dead_code)]
26
/// #[derive(Default)]
27
/// struct SomeOptions {
28
///     foo: i32,
29
///     bar: f32,
30
/// }
31
///
32
/// fn main() {
33
///     let options: SomeOptions = Default::default();
34
/// }
35
/// ```
36
///
37
/// Now, you get all of the default values. Rust implements `Default` for various primitives types.
38
///
39
/// If you want to override a particular option, but still retain the other defaults:
40
///
41
/// ```
42
/// # #[allow(dead_code)]
43
/// # #[derive(Default)]
44
/// # struct SomeOptions {
45
/// #     foo: i32,
46
/// #     bar: f32,
47
/// # }
48
/// fn main() {
49
///     let options = SomeOptions { foo: 42, ..Default::default() };
50
/// }
51
/// ```
52
///
53
/// ## Derivable
54
///
55
/// This trait can be used with `#[derive]` if all of the type's fields implement
56
/// `Default`. When `derive`d, it will use the default value for each field's type.
57
///
58
/// ### `enum`s
59
///
60
/// When using `#[derive(Default)]` on an `enum`, you need to choose which unit variant will be
61
/// default. You do this by placing the `#[default]` attribute on the variant.
62
///
63
/// ```
64
/// #[derive(Default)]
65
/// enum Kind {
66
///     #[default]
67
///     A,
68
///     B,
69
///     C,
70
/// }
71
/// ```
72
///
73
/// You cannot use the `#[default]` attribute on non-unit or non-exhaustive variants.
74
///
75
/// The `#[default]` attribute was stabilized in Rust 1.62.0.
76
///
77
/// ## How can I implement `Default`?
78
///
79
/// Provide an implementation for the `default()` method that returns the value of
80
/// your type that should be the default:
81
///
82
/// ```
83
/// # #![allow(dead_code)]
84
/// enum Kind {
85
///     A,
86
///     B,
87
///     C,
88
/// }
89
///
90
/// impl Default for Kind {
91
///     fn default() -> Self { Kind::A }
92
/// }
93
/// ```
94
///
95
/// # Examples
96
///
97
/// ```
98
/// # #[allow(dead_code)]
99
/// #[derive(Default)]
100
/// struct SomeOptions {
101
///     foo: i32,
102
///     bar: f32,
103
/// }
104
/// ```
105
#[rustc_diagnostic_item = "Default"]
106
#[stable(feature = "rust1", since = "1.0.0")]
107
#[const_trait]
108
#[rustc_const_unstable(feature = "const_default", issue = "143894")]
109
pub trait Default: Sized {
110
    /// Returns the "default value" for a type.
111
    ///
112
    /// Default values are often some kind of initial value, identity value, or anything else that
113
    /// may make sense as a default.
114
    ///
115
    /// # Examples
116
    ///
117
    /// Using built-in default values:
118
    ///
119
    /// ```
120
    /// let i: i8 = Default::default();
121
    /// let (x, y): (Option<String>, f64) = Default::default();
122
    /// let (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();
123
    /// ```
124
    ///
125
    /// Making your own:
126
    ///
127
    /// ```
128
    /// # #[allow(dead_code)]
129
    /// enum Kind {
130
    ///     A,
131
    ///     B,
132
    ///     C,
133
    /// }
134
    ///
135
    /// impl Default for Kind {
136
    ///     fn default() -> Self { Kind::A }
137
    /// }
138
    /// ```
139
    #[stable(feature = "rust1", since = "1.0.0")]
140
    #[rustc_diagnostic_item = "default_fn"]
141
    fn default() -> Self;
142
}
143

            
144
/// Derive macro generating an impl of the trait `Default`.
145
#[rustc_builtin_macro(Default, attributes(default))]
146
#[stable(feature = "builtin_macro_prelude", since = "1.38.0")]
147
#[allow_internal_unstable(core_intrinsics)]
148
#[cfg(not(feature = "ferrocene_certified"))]
149
pub macro Default($item:item) {
150
    /* compiler built-in */
151
}
152

            
153
macro_rules! default_impl {
154
    ($t:ty, $v:expr, $doc:tt) => {
155
        #[stable(feature = "rust1", since = "1.0.0")]
156
        #[rustc_const_unstable(feature = "const_default", issue = "143894")]
157
        impl const Default for $t {
158
            #[inline(always)]
159
            #[doc = $doc]
160
760
            fn default() -> $t {
161
                $v
162
760
            }
163
        }
164
    };
165
}
166

            
167
#[cfg(not(feature = "ferrocene_certified"))]
168
default_impl! { (), (), "Returns the default value of `()`" }
169
#[cfg(not(feature = "ferrocene_certified"))]
170
default_impl! { bool, false, "Returns the default value of `false`" }
171
#[cfg(not(feature = "ferrocene_certified"))]
172
default_impl! { char, '\x00', "Returns the default value of `\\x00`" }
173
#[cfg(not(feature = "ferrocene_certified"))]
174
default_impl! { AsciiChar, AsciiChar::Null, "Returns the default value of `Null`" }
175

            
176
#[cfg(not(feature = "ferrocene_certified"))]
177
default_impl! { usize, 0, "Returns the default value of `0`" }
178
#[cfg(not(feature = "ferrocene_certified"))]
179
default_impl! { u8, 0, "Returns the default value of `0`" }
180
#[cfg(not(feature = "ferrocene_certified"))]
181
default_impl! { u16, 0, "Returns the default value of `0`" }
182
default_impl! { u32, 0, "Returns the default value of `0`" }
183
#[cfg(not(feature = "ferrocene_certified"))]
184
default_impl! { u64, 0, "Returns the default value of `0`" }
185
#[cfg(not(feature = "ferrocene_certified"))]
186
default_impl! { u128, 0, "Returns the default value of `0`" }
187

            
188
#[cfg(not(feature = "ferrocene_certified"))]
189
default_impl! { isize, 0, "Returns the default value of `0`" }
190
#[cfg(not(feature = "ferrocene_certified"))]
191
default_impl! { i8, 0, "Returns the default value of `0`" }
192
#[cfg(not(feature = "ferrocene_certified"))]
193
default_impl! { i16, 0, "Returns the default value of `0`" }
194
#[cfg(not(feature = "ferrocene_certified"))]
195
default_impl! { i32, 0, "Returns the default value of `0`" }
196
#[cfg(not(feature = "ferrocene_certified"))]
197
default_impl! { i64, 0, "Returns the default value of `0`" }
198
#[cfg(not(feature = "ferrocene_certified"))]
199
default_impl! { i128, 0, "Returns the default value of `0`" }
200

            
201
#[cfg(not(feature = "ferrocene_certified"))]
202
default_impl! { f16, 0.0f16, "Returns the default value of `0.0`" }
203
#[cfg(not(feature = "ferrocene_certified"))]
204
default_impl! { f32, 0.0f32, "Returns the default value of `0.0`" }
205
#[cfg(not(feature = "ferrocene_certified"))]
206
default_impl! { f64, 0.0f64, "Returns the default value of `0.0`" }
207
#[cfg(not(feature = "ferrocene_certified"))]
208
default_impl! { f128, 0.0f128, "Returns the default value of `0.0`" }