core/
default.rs

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"))]
6use 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")]
109pub 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"))]
149pub macro Default($item:item) {
150    /* compiler built-in */
151}
152
153macro_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            fn default() -> $t {
161                $v
162            }
163        }
164    };
165}
166
167#[cfg(not(feature = "ferrocene_certified"))]
168default_impl! { (), (), "Returns the default value of `()`" }
169#[cfg(not(feature = "ferrocene_certified"))]
170default_impl! { bool, false, "Returns the default value of `false`" }
171#[cfg(not(feature = "ferrocene_certified"))]
172default_impl! { char, '\x00', "Returns the default value of `\\x00`" }
173#[cfg(not(feature = "ferrocene_certified"))]
174default_impl! { AsciiChar, AsciiChar::Null, "Returns the default value of `Null`" }
175
176#[cfg(not(feature = "ferrocene_certified"))]
177default_impl! { usize, 0, "Returns the default value of `0`" }
178#[cfg(not(feature = "ferrocene_certified"))]
179default_impl! { u8, 0, "Returns the default value of `0`" }
180#[cfg(not(feature = "ferrocene_certified"))]
181default_impl! { u16, 0, "Returns the default value of `0`" }
182default_impl! { u32, 0, "Returns the default value of `0`" }
183#[cfg(not(feature = "ferrocene_certified"))]
184default_impl! { u64, 0, "Returns the default value of `0`" }
185#[cfg(not(feature = "ferrocene_certified"))]
186default_impl! { u128, 0, "Returns the default value of `0`" }
187
188#[cfg(not(feature = "ferrocene_certified"))]
189default_impl! { isize, 0, "Returns the default value of `0`" }
190#[cfg(not(feature = "ferrocene_certified"))]
191default_impl! { i8, 0, "Returns the default value of `0`" }
192#[cfg(not(feature = "ferrocene_certified"))]
193default_impl! { i16, 0, "Returns the default value of `0`" }
194#[cfg(not(feature = "ferrocene_certified"))]
195default_impl! { i32, 0, "Returns the default value of `0`" }
196#[cfg(not(feature = "ferrocene_certified"))]
197default_impl! { i64, 0, "Returns the default value of `0`" }
198#[cfg(not(feature = "ferrocene_certified"))]
199default_impl! { i128, 0, "Returns the default value of `0`" }
200
201#[cfg(not(feature = "ferrocene_certified"))]
202default_impl! { f16, 0.0f16, "Returns the default value of `0.0`" }
203#[cfg(not(feature = "ferrocene_certified"))]
204default_impl! { f32, 0.0f32, "Returns the default value of `0.0`" }
205#[cfg(not(feature = "ferrocene_certified"))]
206default_impl! { f64, 0.0f64, "Returns the default value of `0.0`" }
207#[cfg(not(feature = "ferrocene_certified"))]
208default_impl! { f128, 0.0f128, "Returns the default value of `0.0`" }