]>
Commit | Line | Data |
---|---|---|
c1a9b12d | 1 | #[doc(primitive = "bool")] |
83c7162d XL |
2 | #[doc(alias = "true")] |
3 | #[doc(alias = "false")] | |
c1a9b12d SL |
4 | /// The boolean type. |
5 | /// | |
32a655c1 SL |
6 | /// The `bool` represents a value, which could only be either `true` or `false`. If you cast |
7 | /// a `bool` into an integer, `true` will be 1 and `false` will be 0. | |
7453a54e SL |
8 | /// |
9 | /// # Basic usage | |
10 | /// | |
11 | /// `bool` implements various traits, such as [`BitAnd`], [`BitOr`], [`Not`], etc., | |
12 | /// which allow us to perform boolean operations using `&`, `|` and `!`. | |
13 | /// | |
5869c6ff XL |
14 | /// `if` requires a `bool` value as its conditional. [`assert!`], which is an |
15 | /// important macro in testing, checks whether an expression is `true` and panics | |
16 | /// if it isn't. | |
7453a54e SL |
17 | /// |
18 | /// ``` | |
19 | /// let bool_val = true & false | false; | |
20 | /// assert!(!bool_val); | |
21 | /// ``` | |
22 | /// | |
1b1a35ee XL |
23 | /// [`BitAnd`]: ops::BitAnd |
24 | /// [`BitOr`]: ops::BitOr | |
25 | /// [`Not`]: ops::Not | |
7453a54e SL |
26 | /// |
27 | /// # Examples | |
28 | /// | |
5869c6ff | 29 | /// A trivial example of the usage of `bool`: |
7453a54e SL |
30 | /// |
31 | /// ``` | |
32 | /// let praise_the_borrow_checker = true; | |
33 | /// | |
34 | /// // using the `if` conditional | |
35 | /// if praise_the_borrow_checker { | |
36 | /// println!("oh, yeah!"); | |
37 | /// } else { | |
38 | /// println!("what?!!"); | |
39 | /// } | |
40 | /// | |
41 | /// // ... or, a match pattern | |
42 | /// match praise_the_borrow_checker { | |
43 | /// true => println!("keep praising!"), | |
44 | /// false => println!("you should praise!"), | |
45 | /// } | |
46 | /// ``` | |
47 | /// | |
1b1a35ee | 48 | /// Also, since `bool` implements the [`Copy`] trait, we don't |
7453a54e | 49 | /// have to worry about the move semantics (just like the integer and float primitives). |
32a655c1 SL |
50 | /// |
51 | /// Now an example of `bool` cast to integer type: | |
52 | /// | |
53 | /// ``` | |
54 | /// assert_eq!(true as i32, 1); | |
55 | /// assert_eq!(false as i32, 0); | |
56 | /// ``` | |
57 | #[stable(feature = "rust1", since = "1.0.0")] | |
dfeec247 | 58 | mod prim_bool {} |
c1a9b12d | 59 | |
ff7c6d11 | 60 | #[doc(primitive = "never")] |
83c7162d | 61 | #[doc(alias = "!")] |
ff7c6d11 XL |
62 | // |
63 | /// The `!` type, also called "never". | |
64 | /// | |
65 | /// `!` represents the type of computations which never resolve to any value at all. For example, | |
66 | /// the [`exit`] function `fn exit(code: i32) -> !` exits the process without ever returning, and | |
67 | /// so returns `!`. | |
68 | /// | |
69 | /// `break`, `continue` and `return` expressions also have type `!`. For example we are allowed to | |
70 | /// write: | |
71 | /// | |
72 | /// ``` | |
73 | /// #![feature(never_type)] | |
74 | /// # fn foo() -> u32 { | |
75 | /// let x: ! = { | |
76 | /// return 123 | |
77 | /// }; | |
78 | /// # } | |
79 | /// ``` | |
80 | /// | |
81 | /// Although the `let` is pointless here, it illustrates the meaning of `!`. Since `x` is never | |
82 | /// assigned a value (because `return` returns from the entire function), `x` can be given type | |
83 | /// `!`. We could also replace `return 123` with a `panic!` or a never-ending `loop` and this code | |
84 | /// would still be valid. | |
85 | /// | |
86 | /// A more realistic usage of `!` is in this code: | |
87 | /// | |
88 | /// ``` | |
89 | /// # fn get_a_number() -> Option<u32> { None } | |
90 | /// # loop { | |
91 | /// let num: u32 = match get_a_number() { | |
92 | /// Some(num) => num, | |
93 | /// None => break, | |
94 | /// }; | |
95 | /// # } | |
96 | /// ``` | |
97 | /// | |
98 | /// Both match arms must produce values of type [`u32`], but since `break` never produces a value | |
99 | /// at all we know it can never produce a value which isn't a [`u32`]. This illustrates another | |
100 | /// behaviour of the `!` type - expressions with type `!` will coerce into any other type. | |
101 | /// | |
1b1a35ee XL |
102 | /// [`u32`]: prim@u32 |
103 | /// [`exit`]: process::exit | |
ff7c6d11 XL |
104 | /// |
105 | /// # `!` and generics | |
106 | /// | |
94b46f34 XL |
107 | /// ## Infallible errors |
108 | /// | |
ff7c6d11 XL |
109 | /// The main place you'll see `!` used explicitly is in generic code. Consider the [`FromStr`] |
110 | /// trait: | |
111 | /// | |
112 | /// ``` | |
113 | /// trait FromStr: Sized { | |
114 | /// type Err; | |
115 | /// fn from_str(s: &str) -> Result<Self, Self::Err>; | |
116 | /// } | |
117 | /// ``` | |
118 | /// | |
119 | /// When implementing this trait for [`String`] we need to pick a type for [`Err`]. And since | |
120 | /// converting a string into a string will never result in an error, the appropriate type is `!`. | |
121 | /// (Currently the type actually used is an enum with no variants, though this is only because `!` | |
dc9dc135 | 122 | /// was added to Rust at a later date and it may change in the future.) With an [`Err`] type of |
ff7c6d11 XL |
123 | /// `!`, if we have to call [`String::from_str`] for some reason the result will be a |
124 | /// [`Result<String, !>`] which we can unpack like this: | |
125 | /// | |
5869c6ff XL |
126 | /// ``` |
127 | /// #![feature(exhaustive_patterns)] | |
128 | /// use std::str::FromStr; | |
ff7c6d11 XL |
129 | /// let Ok(s) = String::from_str("hello"); |
130 | /// ``` | |
131 | /// | |
0531ce1d XL |
132 | /// Since the [`Err`] variant contains a `!`, it can never occur. If the `exhaustive_patterns` |
133 | /// feature is present this means we can exhaustively match on [`Result<T, !>`] by just taking the | |
134 | /// [`Ok`] variant. This illustrates another behaviour of `!` - it can be used to "delete" certain | |
135 | /// enum variants from generic types like `Result`. | |
ff7c6d11 | 136 | /// |
94b46f34 XL |
137 | /// ## Infinite loops |
138 | /// | |
139 | /// While [`Result<T, !>`] is very useful for removing errors, `!` can also be used to remove | |
140 | /// successes as well. If we think of [`Result<T, !>`] as "if this function returns, it has not | |
141 | /// errored," we get a very intuitive idea of [`Result<!, E>`] as well: if the function returns, it | |
142 | /// *has* errored. | |
143 | /// | |
144 | /// For example, consider the case of a simple web server, which can be simplified to: | |
145 | /// | |
146 | /// ```ignore (hypothetical-example) | |
147 | /// loop { | |
148 | /// let (client, request) = get_request().expect("disconnected"); | |
149 | /// let response = request.process(); | |
150 | /// response.send(client); | |
151 | /// } | |
152 | /// ``` | |
153 | /// | |
154 | /// Currently, this isn't ideal, because we simply panic whenever we fail to get a new connection. | |
155 | /// Instead, we'd like to keep track of this error, like this: | |
156 | /// | |
157 | /// ```ignore (hypothetical-example) | |
158 | /// loop { | |
159 | /// match get_request() { | |
160 | /// Err(err) => break err, | |
161 | /// Ok((client, request)) => { | |
162 | /// let response = request.process(); | |
163 | /// response.send(client); | |
164 | /// }, | |
165 | /// } | |
166 | /// } | |
167 | /// ``` | |
168 | /// | |
169 | /// Now, when the server disconnects, we exit the loop with an error instead of panicking. While it | |
170 | /// might be intuitive to simply return the error, we might want to wrap it in a [`Result<!, E>`] | |
171 | /// instead: | |
172 | /// | |
173 | /// ```ignore (hypothetical-example) | |
174 | /// fn server_loop() -> Result<!, ConnectionError> { | |
175 | /// loop { | |
176 | /// let (client, request) = get_request()?; | |
177 | /// let response = request.process(); | |
178 | /// response.send(client); | |
179 | /// } | |
180 | /// } | |
181 | /// ``` | |
182 | /// | |
183 | /// Now, we can use `?` instead of `match`, and the return type makes a lot more sense: if the loop | |
184 | /// ever stops, it means that an error occurred. We don't even have to wrap the loop in an `Ok` | |
185 | /// because `!` coerces to `Result<!, ConnectionError>` automatically. | |
186 | /// | |
1b1a35ee | 187 | /// [`String::from_str`]: str::FromStr::from_str |
1b1a35ee XL |
188 | /// [`String`]: string::String |
189 | /// [`FromStr`]: str::FromStr | |
ff7c6d11 XL |
190 | /// |
191 | /// # `!` and traits | |
192 | /// | |
193 | /// When writing your own traits, `!` should have an `impl` whenever there is an obvious `impl` | |
1b1a35ee XL |
194 | /// which doesn't `panic!`. The reason is that functions returning an `impl Trait` where `!` |
195 | /// does not have an `impl` of `Trait` cannot diverge as their only possible code path. In other | |
196 | /// words, they can't return `!` from every code path. As an example, this code doesn't compile: | |
197 | /// | |
198 | /// ```compile_fail | |
fc512014 | 199 | /// use std::ops::Add; |
1b1a35ee XL |
200 | /// |
201 | /// fn foo() -> impl Add<u32> { | |
202 | /// unimplemented!() | |
203 | /// } | |
204 | /// ``` | |
205 | /// | |
206 | /// But this code does: | |
207 | /// | |
208 | /// ``` | |
fc512014 | 209 | /// use std::ops::Add; |
1b1a35ee XL |
210 | /// |
211 | /// fn foo() -> impl Add<u32> { | |
212 | /// if true { | |
213 | /// unimplemented!() | |
214 | /// } else { | |
215 | /// 0 | |
216 | /// } | |
217 | /// } | |
218 | /// ``` | |
219 | /// | |
220 | /// The reason is that, in the first example, there are many possible types that `!` could coerce | |
221 | /// to, because many types implement `Add<u32>`. However, in the second example, | |
222 | /// the `else` branch returns a `0`, which the compiler infers from the return type to be of type | |
223 | /// `u32`. Since `u32` is a concrete type, `!` can and will be coerced to it. See issue [#36375] | |
224 | /// for more information on this quirk of `!`. | |
225 | /// | |
226 | /// [#36375]: https://github.com/rust-lang/rust/issues/36375 | |
227 | /// | |
228 | /// As it turns out, though, most traits can have an `impl` for `!`. Take [`Debug`] | |
ff7c6d11 XL |
229 | /// for example: |
230 | /// | |
231 | /// ``` | |
0531ce1d | 232 | /// #![feature(never_type)] |
ff7c6d11 XL |
233 | /// # use std::fmt; |
234 | /// # trait Debug { | |
1b1a35ee | 235 | /// # fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result; |
ff7c6d11 XL |
236 | /// # } |
237 | /// impl Debug for ! { | |
532ac7d7 | 238 | /// fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { |
ff7c6d11 XL |
239 | /// *self |
240 | /// } | |
241 | /// } | |
242 | /// ``` | |
243 | /// | |
244 | /// Once again we're using `!`'s ability to coerce into any other type, in this case | |
245 | /// [`fmt::Result`]. Since this method takes a `&!` as an argument we know that it can never be | |
246 | /// called (because there is no value of type `!` for it to be called with). Writing `*self` | |
247 | /// essentially tells the compiler "We know that this code can never be run, so just treat the | |
0bf4aa26 | 248 | /// entire function body as having type [`fmt::Result`]". This pattern can be used a lot when |
ff7c6d11 | 249 | /// implementing traits for `!`. Generally, any trait which only has methods which take a `self` |
0bf4aa26 | 250 | /// parameter should have such an impl. |
ff7c6d11 XL |
251 | /// |
252 | /// On the other hand, one trait which would not be appropriate to implement is [`Default`]: | |
253 | /// | |
254 | /// ``` | |
255 | /// trait Default { | |
256 | /// fn default() -> Self; | |
257 | /// } | |
258 | /// ``` | |
259 | /// | |
260 | /// Since `!` has no values, it has no default value either. It's true that we could write an | |
261 | /// `impl` for this which simply panics, but the same is true for any type (we could `impl | |
262 | /// Default` for (eg.) [`File`] by just making [`default()`] panic.) | |
263 | /// | |
1b1a35ee XL |
264 | /// [`File`]: fs::File |
265 | /// [`Debug`]: fmt::Debug | |
266 | /// [`default()`]: Default::default | |
ff7c6d11 | 267 | /// |
b7449926 | 268 | #[unstable(feature = "never_type", issue = "35121")] |
dfeec247 | 269 | mod prim_never {} |
ff7c6d11 | 270 | |
c1a9b12d SL |
271 | #[doc(primitive = "char")] |
272 | // | |
92a42be0 | 273 | /// A character type. |
c1a9b12d | 274 | /// |
92a42be0 SL |
275 | /// The `char` type represents a single character. More specifically, since |
276 | /// 'character' isn't a well-defined concept in Unicode, `char` is a '[Unicode | |
277 | /// scalar value]', which is similar to, but not the same as, a '[Unicode code | |
278 | /// point]'. | |
c1a9b12d | 279 | /// |
92a42be0 SL |
280 | /// [Unicode scalar value]: http://www.unicode.org/glossary/#unicode_scalar_value |
281 | /// [Unicode code point]: http://www.unicode.org/glossary/#code_point | |
c1a9b12d | 282 | /// |
92a42be0 SL |
283 | /// This documentation describes a number of methods and trait implementations on the |
284 | /// `char` type. For technical reasons, there is additional, separate | |
285 | /// documentation in [the `std::char` module](char/index.html) as well. | |
c1a9b12d | 286 | /// |
92a42be0 SL |
287 | /// # Representation |
288 | /// | |
289 | /// `char` is always four bytes in size. This is a different representation than | |
54a0048b | 290 | /// a given character would have as part of a [`String`]. For example: |
92a42be0 SL |
291 | /// |
292 | /// ``` | |
293 | /// let v = vec!['h', 'e', 'l', 'l', 'o']; | |
294 | /// | |
295 | /// // five elements times four bytes for each element | |
296 | /// assert_eq!(20, v.len() * std::mem::size_of::<char>()); | |
297 | /// | |
298 | /// let s = String::from("hello"); | |
299 | /// | |
300 | /// // five elements times one byte per element | |
301 | /// assert_eq!(5, s.len() * std::mem::size_of::<u8>()); | |
302 | /// ``` | |
303 | /// | |
304 | /// [`String`]: string/struct.String.html | |
305 | /// | |
306 | /// As always, remember that a human intuition for 'character' may not map to | |
3b2f2976 | 307 | /// Unicode's definitions. For example, despite looking similar, the 'é' |
48663c56 | 308 | /// character is one Unicode code point while 'é' is two Unicode code points: |
92a42be0 SL |
309 | /// |
310 | /// ``` | |
3b2f2976 XL |
311 | /// let mut chars = "é".chars(); |
312 | /// // U+00e9: 'latin small letter e with acute' | |
313 | /// assert_eq!(Some('\u{00e9}'), chars.next()); | |
314 | /// assert_eq!(None, chars.next()); | |
92a42be0 | 315 | /// |
3b2f2976 XL |
316 | /// let mut chars = "é".chars(); |
317 | /// // U+0065: 'latin small letter e' | |
318 | /// assert_eq!(Some('\u{0065}'), chars.next()); | |
319 | /// // U+0301: 'combining acute accent' | |
320 | /// assert_eq!(Some('\u{0301}'), chars.next()); | |
321 | /// assert_eq!(None, chars.next()); | |
92a42be0 SL |
322 | /// ``` |
323 | /// | |
3b2f2976 XL |
324 | /// This means that the contents of the first string above _will_ fit into a |
325 | /// `char` while the contents of the second string _will not_. Trying to create | |
326 | /// a `char` literal with the contents of the second string gives an error: | |
92a42be0 SL |
327 | /// |
328 | /// ```text | |
3b2f2976 XL |
329 | /// error: character literal may only contain one codepoint: 'é' |
330 | /// let c = 'é'; | |
0731742a | 331 | /// ^^^ |
92a42be0 SL |
332 | /// ``` |
333 | /// | |
54a0048b SL |
334 | /// Another implication of the 4-byte fixed size of a `char` is that |
335 | /// per-`char` processing can end up using a lot more memory: | |
92a42be0 SL |
336 | /// |
337 | /// ``` | |
338 | /// let s = String::from("love: ❤️"); | |
339 | /// let v: Vec<char> = s.chars().collect(); | |
340 | /// | |
0bf4aa26 XL |
341 | /// assert_eq!(12, std::mem::size_of_val(&s[..])); |
342 | /// assert_eq!(32, std::mem::size_of_val(&v[..])); | |
92a42be0 | 343 | /// ``` |
32a655c1 | 344 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 345 | mod prim_char {} |
c1a9b12d SL |
346 | |
347 | #[doc(primitive = "unit")] | |
348 | // | |
ba9703b0 | 349 | /// The `()` type, also called "unit". |
c1a9b12d SL |
350 | /// |
351 | /// The `()` type has exactly one value `()`, and is used when there | |
352 | /// is no other meaningful value that could be returned. `()` is most | |
353 | /// commonly seen implicitly: functions without a `-> ...` implicitly | |
354 | /// have return type `()`, that is, these are equivalent: | |
355 | /// | |
356 | /// ```rust | |
357 | /// fn long() -> () {} | |
358 | /// | |
359 | /// fn short() {} | |
360 | /// ``` | |
361 | /// | |
362 | /// The semicolon `;` can be used to discard the result of an | |
363 | /// expression at the end of a block, making the expression (and thus | |
364 | /// the block) evaluate to `()`. For example, | |
365 | /// | |
366 | /// ```rust | |
367 | /// fn returns_i64() -> i64 { | |
368 | /// 1i64 | |
369 | /// } | |
370 | /// fn returns_unit() { | |
371 | /// 1i64; | |
372 | /// } | |
373 | /// | |
374 | /// let is_i64 = { | |
375 | /// returns_i64() | |
376 | /// }; | |
377 | /// let is_unit = { | |
378 | /// returns_i64(); | |
379 | /// }; | |
380 | /// ``` | |
381 | /// | |
32a655c1 | 382 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 383 | mod prim_unit {} |
c1a9b12d | 384 | |
1b1a35ee | 385 | #[doc(alias = "ptr")] |
c1a9b12d SL |
386 | #[doc(primitive = "pointer")] |
387 | // | |
388 | /// Raw, unsafe pointers, `*const T`, and `*mut T`. | |
389 | /// | |
29967ef6 | 390 | /// *[See also the `std::ptr` module](ptr).* |
94b46f34 | 391 | /// |
416331ca XL |
392 | /// Working with raw pointers in Rust is uncommon, typically limited to a few patterns. |
393 | /// Raw pointers can be unaligned or [`null`]. However, when a raw pointer is | |
394 | /// dereferenced (using the `*` operator), it must be non-null and aligned. | |
395 | /// | |
396 | /// Storing through a raw pointer using `*ptr = data` calls `drop` on the old value, so | |
397 | /// [`write`] must be used if the type has drop glue and memory is not already | |
398 | /// initialized - otherwise `drop` would be called on the uninitialized memory. | |
c1a9b12d | 399 | /// |
3b2f2976 XL |
400 | /// Use the [`null`] and [`null_mut`] functions to create null pointers, and the |
401 | /// [`is_null`] method of the `*const T` and `*mut T` types to check for null. | |
402 | /// The `*const T` and `*mut T` types also define the [`offset`] method, for | |
403 | /// pointer math. | |
c1a9b12d SL |
404 | /// |
405 | /// # Common ways to create raw pointers | |
406 | /// | |
407 | /// ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`). | |
408 | /// | |
409 | /// ``` | |
410 | /// let my_num: i32 = 10; | |
411 | /// let my_num_ptr: *const i32 = &my_num; | |
412 | /// let mut my_speed: i32 = 88; | |
413 | /// let my_speed_ptr: *mut i32 = &mut my_speed; | |
414 | /// ``` | |
415 | /// | |
416 | /// To get a pointer to a boxed value, dereference the box: | |
417 | /// | |
418 | /// ``` | |
419 | /// let my_num: Box<i32> = Box::new(10); | |
420 | /// let my_num_ptr: *const i32 = &*my_num; | |
421 | /// let mut my_speed: Box<i32> = Box::new(88); | |
422 | /// let my_speed_ptr: *mut i32 = &mut *my_speed; | |
423 | /// ``` | |
424 | /// | |
425 | /// This does not take ownership of the original allocation | |
426 | /// and requires no resource management later, | |
427 | /// but you must not use the pointer after its lifetime. | |
428 | /// | |
429 | /// ## 2. Consume a box (`Box<T>`). | |
430 | /// | |
cc61c64b | 431 | /// The [`into_raw`] function consumes a box and returns |
c1a9b12d SL |
432 | /// the raw pointer. It doesn't destroy `T` or deallocate any memory. |
433 | /// | |
434 | /// ``` | |
c1a9b12d SL |
435 | /// let my_speed: Box<i32> = Box::new(88); |
436 | /// let my_speed: *mut i32 = Box::into_raw(my_speed); | |
437 | /// | |
438 | /// // By taking ownership of the original `Box<T>` though | |
439 | /// // we are obligated to put it together later to be destroyed. | |
440 | /// unsafe { | |
441 | /// drop(Box::from_raw(my_speed)); | |
442 | /// } | |
443 | /// ``` | |
444 | /// | |
cc61c64b | 445 | /// Note that here the call to [`drop`] is for clarity - it indicates |
c1a9b12d SL |
446 | /// that we are done with the given value and it should be destroyed. |
447 | /// | |
448 | /// ## 3. Get it from C. | |
449 | /// | |
450 | /// ``` | |
0731742a | 451 | /// # #![feature(rustc_private)] |
c1a9b12d SL |
452 | /// extern crate libc; |
453 | /// | |
454 | /// use std::mem; | |
455 | /// | |
e74abb32 XL |
456 | /// unsafe { |
457 | /// let my_num: *mut i32 = libc::malloc(mem::size_of::<i32>()) as *mut i32; | |
458 | /// if my_num.is_null() { | |
459 | /// panic!("failed to allocate memory"); | |
c1a9b12d | 460 | /// } |
e74abb32 | 461 | /// libc::free(my_num as *mut libc::c_void); |
c1a9b12d SL |
462 | /// } |
463 | /// ``` | |
464 | /// | |
465 | /// Usually you wouldn't literally use `malloc` and `free` from Rust, | |
466 | /// but C APIs hand out a lot of pointers generally, so are a common source | |
467 | /// of raw pointers in Rust. | |
468 | /// | |
1b1a35ee XL |
469 | /// [`null`]: ptr::null |
470 | /// [`null_mut`]: ptr::null_mut | |
6a06907d XL |
471 | /// [`is_null`]: pointer::is_null |
472 | /// [`offset`]: pointer::offset | |
1b1a35ee XL |
473 | /// [`into_raw`]: Box::into_raw |
474 | /// [`drop`]: mem::drop | |
475 | /// [`write`]: ptr::write | |
32a655c1 | 476 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 477 | mod prim_pointer {} |
c1a9b12d | 478 | |
fc512014 XL |
479 | #[doc(alias = "[]")] |
480 | #[doc(alias = "[T;N]")] // unfortunately, rustdoc doesn't have fuzzy search for aliases | |
481 | #[doc(alias = "[T; N]")] | |
c1a9b12d | 482 | #[doc(primitive = "array")] |
92a42be0 | 483 | /// A fixed-size array, denoted `[T; N]`, for the element type, `T`, and the |
9e0c209e | 484 | /// non-negative compile-time constant size, `N`. |
c1a9b12d | 485 | /// |
9e0c209e | 486 | /// There are two syntactic forms for creating an array: |
c1a9b12d | 487 | /// |
0731742a | 488 | /// * A list with each element, i.e., `[x, y, z]`. |
9e0c209e | 489 | /// * A repeat expression `[x; N]`, which produces an array with `N` copies of `x`. |
1b1a35ee | 490 | /// The type of `x` must be [`Copy`]. |
c1a9b12d | 491 | /// |
fc512014 XL |
492 | /// Note that `[expr; 0]` is allowed, and produces an empty array. |
493 | /// This will still evaluate `expr`, however, and immediately drop the resulting value, so | |
494 | /// be mindful of side effects. | |
495 | /// | |
3dfed10e | 496 | /// Arrays of *any* size implement the following traits if the element type allows it: |
c1a9b12d | 497 | /// |
29967ef6 XL |
498 | /// - [`Copy`] |
499 | /// - [`Clone`] | |
1b1a35ee XL |
500 | /// - [`Debug`] |
501 | /// - [`IntoIterator`] (implemented for `&[T; N]` and `&mut [T; N]`) | |
502 | /// - [`PartialEq`], [`PartialOrd`], [`Eq`], [`Ord`] | |
503 | /// - [`Hash`] | |
504 | /// - [`AsRef`], [`AsMut`] | |
505 | /// - [`Borrow`], [`BorrowMut`] | |
c1a9b12d | 506 | /// |
29967ef6 | 507 | /// Arrays of sizes from 0 to 32 (inclusive) implement the [`Default`] trait |
3dfed10e | 508 | /// if the element type allows it. As a stopgap, trait implementations are |
9e0c209e | 509 | /// statically generated up to size 32. |
c1a9b12d | 510 | /// |
9e0c209e SL |
511 | /// Arrays coerce to [slices (`[T]`)][slice], so a slice method may be called on |
512 | /// an array. Indeed, this provides most of the API for working with arrays. | |
513 | /// Slices have a dynamic size and do not coerce to arrays. | |
c1a9b12d | 514 | /// |
1b1a35ee XL |
515 | /// You can move elements out of an array with a [slice pattern]. If you want |
516 | /// one element, see [`mem::replace`]. | |
9e0c209e | 517 | /// |
c1a9b12d SL |
518 | /// # Examples |
519 | /// | |
520 | /// ``` | |
521 | /// let mut array: [i32; 3] = [0; 3]; | |
522 | /// | |
523 | /// array[1] = 1; | |
524 | /// array[2] = 2; | |
525 | /// | |
526 | /// assert_eq!([1, 2], &array[1..]); | |
527 | /// | |
528 | /// // This loop prints: 0 1 2 | |
529 | /// for x in &array { | |
530 | /// print!("{} ", x); | |
531 | /// } | |
9e0c209e SL |
532 | /// ``` |
533 | /// | |
534 | /// An array itself is not iterable: | |
535 | /// | |
041b39d2 | 536 | /// ```compile_fail,E0277 |
9e0c209e SL |
537 | /// let array: [i32; 3] = [0; 3]; |
538 | /// | |
539 | /// for x in array { } | |
540 | /// // error: the trait bound `[i32; 3]: std::iter::Iterator` is not satisfied | |
541 | /// ``` | |
542 | /// | |
543 | /// The solution is to coerce the array to a slice by calling a slice method: | |
544 | /// | |
545 | /// ``` | |
546 | /// # let array: [i32; 3] = [0; 3]; | |
547 | /// for x in array.iter() { } | |
548 | /// ``` | |
549 | /// | |
3dfed10e | 550 | /// You can also use the array reference's [`IntoIterator`] implementation: |
c1a9b12d SL |
551 | /// |
552 | /// ``` | |
9e0c209e SL |
553 | /// # let array: [i32; 3] = [0; 3]; |
554 | /// for x in &array { } | |
555 | /// ``` | |
c1a9b12d | 556 | /// |
1b1a35ee | 557 | /// You can use a [slice pattern] to move elements out of an array: |
dc9dc135 XL |
558 | /// |
559 | /// ``` | |
560 | /// fn move_away(_: String) { /* Do interesting things. */ } | |
561 | /// | |
562 | /// let [john, roa] = ["John".to_string(), "Roa".to_string()]; | |
563 | /// move_away(john); | |
564 | /// move_away(roa); | |
565 | /// ``` | |
566 | /// | |
6a06907d | 567 | /// [slice]: prim@slice |
1b1a35ee XL |
568 | /// [`Debug`]: fmt::Debug |
569 | /// [`Hash`]: hash::Hash | |
570 | /// [`Borrow`]: borrow::Borrow | |
571 | /// [`BorrowMut`]: borrow::BorrowMut | |
572 | /// [slice pattern]: ../reference/patterns.html#slice-patterns | |
32a655c1 | 573 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 574 | mod prim_array {} |
c1a9b12d SL |
575 | |
576 | #[doc(primitive = "slice")] | |
83c7162d XL |
577 | #[doc(alias = "[")] |
578 | #[doc(alias = "]")] | |
579 | #[doc(alias = "[]")] | |
e74abb32 XL |
580 | /// A dynamically-sized view into a contiguous sequence, `[T]`. Contiguous here |
581 | /// means that elements are laid out so that every element is the same | |
582 | /// distance from its neighbors. | |
c1a9b12d | 583 | /// |
29967ef6 | 584 | /// *[See also the `std::slice` module](crate::slice).* |
94b46f34 | 585 | /// |
c1a9b12d SL |
586 | /// Slices are a view into a block of memory represented as a pointer and a |
587 | /// length. | |
588 | /// | |
589 | /// ``` | |
590 | /// // slicing a Vec | |
591 | /// let vec = vec![1, 2, 3]; | |
592 | /// let int_slice = &vec[..]; | |
593 | /// // coercing an array to a slice | |
594 | /// let str_slice: &[&str] = &["one", "two", "three"]; | |
595 | /// ``` | |
596 | /// | |
597 | /// Slices are either mutable or shared. The shared slice type is `&[T]`, | |
598 | /// while the mutable slice type is `&mut [T]`, where `T` represents the element | |
599 | /// type. For example, you can mutate the block of memory that a mutable slice | |
600 | /// points to: | |
601 | /// | |
602 | /// ``` | |
0731742a XL |
603 | /// let mut x = [1, 2, 3]; |
604 | /// let x = &mut x[..]; // Take a full slice of `x`. | |
c1a9b12d SL |
605 | /// x[1] = 7; |
606 | /// assert_eq!(x, &[1, 7, 3]); | |
607 | /// ``` | |
3dfed10e XL |
608 | /// |
609 | /// As slices store the length of the sequence they refer to, they have twice | |
610 | /// the size of pointers to [`Sized`](marker/trait.Sized.html) types. | |
611 | /// Also see the reference on | |
612 | /// [dynamically sized types](../reference/dynamically-sized-types.html). | |
613 | /// | |
614 | /// ``` | |
615 | /// # use std::rc::Rc; | |
616 | /// let pointer_size = std::mem::size_of::<&u8>(); | |
617 | /// assert_eq!(2 * pointer_size, std::mem::size_of::<&[u8]>()); | |
618 | /// assert_eq!(2 * pointer_size, std::mem::size_of::<*const [u8]>()); | |
619 | /// assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>()); | |
620 | /// assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>()); | |
621 | /// ``` | |
32a655c1 | 622 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 623 | mod prim_slice {} |
c1a9b12d SL |
624 | |
625 | #[doc(primitive = "str")] | |
626 | // | |
92a42be0 SL |
627 | /// String slices. |
628 | /// | |
29967ef6 | 629 | /// *[See also the `std::str` module](crate::str).* |
94b46f34 | 630 | /// |
92a42be0 SL |
631 | /// The `str` type, also called a 'string slice', is the most primitive string |
632 | /// type. It is usually seen in its borrowed form, `&str`. It is also the type | |
633 | /// of string literals, `&'static str`. | |
634 | /// | |
94b46f34 | 635 | /// String slices are always valid UTF-8. |
c1a9b12d SL |
636 | /// |
637 | /// # Examples | |
638 | /// | |
92a42be0 | 639 | /// String literals are string slices: |
c1a9b12d SL |
640 | /// |
641 | /// ``` | |
92a42be0 SL |
642 | /// let hello = "Hello, world!"; |
643 | /// | |
644 | /// // with an explicit type annotation | |
645 | /// let hello: &'static str = "Hello, world!"; | |
c1a9b12d SL |
646 | /// ``` |
647 | /// | |
92a42be0 SL |
648 | /// They are `'static` because they're stored directly in the final binary, and |
649 | /// so will be valid for the `'static` duration. | |
c1a9b12d | 650 | /// |
92a42be0 SL |
651 | /// # Representation |
652 | /// | |
653 | /// A `&str` is made up of two components: a pointer to some bytes, and a | |
cc61c64b | 654 | /// length. You can look at these with the [`as_ptr`] and [`len`] methods: |
c1a9b12d SL |
655 | /// |
656 | /// ``` | |
92a42be0 SL |
657 | /// use std::slice; |
658 | /// use std::str; | |
c1a9b12d | 659 | /// |
92a42be0 | 660 | /// let story = "Once upon a time..."; |
c1a9b12d | 661 | /// |
92a42be0 SL |
662 | /// let ptr = story.as_ptr(); |
663 | /// let len = story.len(); | |
c1a9b12d | 664 | /// |
9cc50fc6 | 665 | /// // story has nineteen bytes |
92a42be0 | 666 | /// assert_eq!(19, len); |
c1a9b12d | 667 | /// |
54a0048b | 668 | /// // We can re-build a str out of ptr and len. This is all unsafe because |
92a42be0 SL |
669 | /// // we are responsible for making sure the two components are valid: |
670 | /// let s = unsafe { | |
671 | /// // First, we build a &[u8]... | |
672 | /// let slice = slice::from_raw_parts(ptr, len); | |
673 | /// | |
674 | /// // ... and then convert that slice into a string slice | |
675 | /// str::from_utf8(slice) | |
676 | /// }; | |
677 | /// | |
678 | /// assert_eq!(s, Ok(story)); | |
679 | /// ``` | |
c1a9b12d | 680 | /// |
1b1a35ee XL |
681 | /// [`as_ptr`]: str::as_ptr |
682 | /// [`len`]: str::len | |
9e0c209e SL |
683 | /// |
684 | /// Note: This example shows the internals of `&str`. `unsafe` should not be | |
e1599b0c | 685 | /// used to get a string slice under normal circumstances. Use `as_str` |
9e0c209e | 686 | /// instead. |
32a655c1 | 687 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 688 | mod prim_str {} |
c1a9b12d SL |
689 | |
690 | #[doc(primitive = "tuple")] | |
83c7162d XL |
691 | #[doc(alias = "(")] |
692 | #[doc(alias = ")")] | |
693 | #[doc(alias = "()")] | |
c1a9b12d SL |
694 | // |
695 | /// A finite heterogeneous sequence, `(T, U, ..)`. | |
696 | /// | |
7453a54e SL |
697 | /// Let's cover each of those in turn: |
698 | /// | |
699 | /// Tuples are *finite*. In other words, a tuple has a length. Here's a tuple | |
700 | /// of length `3`: | |
701 | /// | |
702 | /// ``` | |
703 | /// ("hello", 5, 'c'); | |
704 | /// ``` | |
705 | /// | |
706 | /// 'Length' is also sometimes called 'arity' here; each tuple of a different | |
707 | /// length is a different, distinct type. | |
708 | /// | |
709 | /// Tuples are *heterogeneous*. This means that each element of the tuple can | |
710 | /// have a different type. In that tuple above, it has the type: | |
711 | /// | |
041b39d2 XL |
712 | /// ``` |
713 | /// # let _: | |
7453a54e | 714 | /// (&'static str, i32, char) |
041b39d2 | 715 | /// # = ("hello", 5, 'c'); |
7453a54e SL |
716 | /// ``` |
717 | /// | |
718 | /// Tuples are a *sequence*. This means that they can be accessed by position; | |
719 | /// this is called 'tuple indexing', and it looks like this: | |
720 | /// | |
721 | /// ```rust | |
722 | /// let tuple = ("hello", 5, 'c'); | |
723 | /// | |
724 | /// assert_eq!(tuple.0, "hello"); | |
725 | /// assert_eq!(tuple.1, 5); | |
726 | /// assert_eq!(tuple.2, 'c'); | |
727 | /// ``` | |
728 | /// | |
dc9dc135 XL |
729 | /// The sequential nature of the tuple applies to its implementations of various |
730 | /// traits. For example, in `PartialOrd` and `Ord`, the elements are compared | |
731 | /// sequentially until the first non-equal set is found. | |
732 | /// | |
13cf67c4 | 733 | /// For more about tuples, see [the book](../book/ch03-02-data-types.html#the-tuple-type). |
c1a9b12d | 734 | /// |
7453a54e | 735 | /// # Trait implementations |
c1a9b12d | 736 | /// |
54a0048b SL |
737 | /// If every type inside a tuple implements one of the following traits, then a |
738 | /// tuple itself also implements it. | |
c1a9b12d | 739 | /// |
7453a54e | 740 | /// * [`Clone`] |
54a0048b | 741 | /// * [`Copy`] |
7453a54e SL |
742 | /// * [`PartialEq`] |
743 | /// * [`Eq`] | |
744 | /// * [`PartialOrd`] | |
745 | /// * [`Ord`] | |
746 | /// * [`Debug`] | |
747 | /// * [`Default`] | |
748 | /// * [`Hash`] | |
749 | /// | |
1b1a35ee XL |
750 | /// [`Debug`]: fmt::Debug |
751 | /// [`Hash`]: hash::Hash | |
7453a54e SL |
752 | /// |
753 | /// Due to a temporary restriction in Rust's type system, these traits are only | |
32a655c1 | 754 | /// implemented on tuples of arity 12 or less. In the future, this may change. |
c1a9b12d SL |
755 | /// |
756 | /// # Examples | |
757 | /// | |
7453a54e | 758 | /// Basic usage: |
c1a9b12d SL |
759 | /// |
760 | /// ``` | |
7453a54e | 761 | /// let tuple = ("hello", 5, 'c'); |
c1a9b12d | 762 | /// |
7453a54e | 763 | /// assert_eq!(tuple.0, "hello"); |
c1a9b12d SL |
764 | /// ``` |
765 | /// | |
7453a54e SL |
766 | /// Tuples are often used as a return type when you want to return more than |
767 | /// one value: | |
c1a9b12d SL |
768 | /// |
769 | /// ``` | |
7453a54e SL |
770 | /// fn calculate_point() -> (i32, i32) { |
771 | /// // Don't do a calculation, that's not the point of the example | |
772 | /// (4, 5) | |
773 | /// } | |
774 | /// | |
775 | /// let point = calculate_point(); | |
776 | /// | |
777 | /// assert_eq!(point.0, 4); | |
778 | /// assert_eq!(point.1, 5); | |
779 | /// | |
780 | /// // Combining this with patterns can be nicer. | |
c1a9b12d | 781 | /// |
7453a54e | 782 | /// let (x, y) = calculate_point(); |
c1a9b12d | 783 | /// |
7453a54e SL |
784 | /// assert_eq!(x, 4); |
785 | /// assert_eq!(y, 5); | |
c1a9b12d SL |
786 | /// ``` |
787 | /// | |
32a655c1 | 788 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 789 | mod prim_tuple {} |
c1a9b12d SL |
790 | |
791 | #[doc(primitive = "f32")] | |
3dfed10e XL |
792 | /// A 32-bit floating point type (specifically, the "binary32" type defined in IEEE 754-2008). |
793 | /// | |
794 | /// This type can represent a wide range of decimal numbers, like `3.5`, `27`, | |
795 | /// `-113.75`, `0.0078125`, `34359738368`, `0`, `-1`. So unlike integer types | |
796 | /// (such as `i32`), floating point types can represent non-integer numbers, | |
797 | /// too. | |
798 | /// | |
799 | /// However, being able to represent this wide range of numbers comes at the | |
800 | /// cost of precision: floats can only represent some of the real numbers and | |
801 | /// calculation with floats round to a nearby representable number. For example, | |
802 | /// `5.0` and `1.0` can be exactly represented as `f32`, but `1.0 / 5.0` results | |
803 | /// in `0.20000000298023223876953125` since `0.2` cannot be exactly represented | |
29967ef6 | 804 | /// as `f32`. Note, however, that printing floats with `println` and friends will |
3dfed10e XL |
805 | /// often discard insignificant digits: `println!("{}", 1.0f32 / 5.0f32)` will |
806 | /// print `0.2`. | |
807 | /// | |
808 | /// Additionally, `f32` can represent a couple of special values: | |
809 | /// | |
810 | /// - `-0`: this is just due to how floats are encoded. It is semantically | |
811 | /// equivalent to `0` and `-0.0 == 0.0` results in `true`. | |
812 | /// - [∞](#associatedconstant.INFINITY) and | |
813 | /// [−∞](#associatedconstant.NEG_INFINITY): these result from calculations | |
814 | /// like `1.0 / 0.0`. | |
815 | /// - [NaN (not a number)](#associatedconstant.NAN): this value results from | |
816 | /// calculations like `(-1.0).sqrt()`. NaN has some potentially unexpected | |
817 | /// behavior: it is unequal to any float, including itself! It is also neither | |
818 | /// smaller nor greater than any float, making it impossible to sort. Lastly, | |
819 | /// it is considered infectious as almost all calculations where one of the | |
820 | /// operands is NaN will also result in NaN. | |
821 | /// | |
822 | /// For more information on floating point numbers, see [Wikipedia][wikipedia]. | |
c1a9b12d | 823 | /// |
29967ef6 | 824 | /// *[See also the `std::f32::consts` module](crate::f32::consts).* |
c1a9b12d | 825 | /// |
3dfed10e | 826 | /// [wikipedia]: https://en.wikipedia.org/wiki/Single-precision_floating-point_format |
32a655c1 | 827 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 828 | mod prim_f32 {} |
c1a9b12d SL |
829 | |
830 | #[doc(primitive = "f64")] | |
3dfed10e XL |
831 | /// A 64-bit floating point type (specifically, the "binary64" type defined in IEEE 754-2008). |
832 | /// | |
1b1a35ee | 833 | /// This type is very similar to [`f32`], but has increased |
3dfed10e | 834 | /// precision by using twice as many bits. Please see [the documentation for |
1b1a35ee | 835 | /// `f32`][`f32`] or [Wikipedia on double precision |
3dfed10e | 836 | /// values][wikipedia] for more information. |
c1a9b12d | 837 | /// |
29967ef6 | 838 | /// *[See also the `std::f64::consts` module](crate::f64::consts).* |
c1a9b12d | 839 | /// |
1b1a35ee | 840 | /// [`f32`]: prim@f32 |
3dfed10e | 841 | /// [wikipedia]: https://en.wikipedia.org/wiki/Double-precision_floating-point_format |
32a655c1 | 842 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 843 | mod prim_f64 {} |
c1a9b12d SL |
844 | |
845 | #[doc(primitive = "i8")] | |
846 | // | |
847 | /// The 8-bit signed integer type. | |
32a655c1 | 848 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 849 | mod prim_i8 {} |
c1a9b12d SL |
850 | |
851 | #[doc(primitive = "i16")] | |
852 | // | |
853 | /// The 16-bit signed integer type. | |
32a655c1 | 854 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 855 | mod prim_i16 {} |
c1a9b12d SL |
856 | |
857 | #[doc(primitive = "i32")] | |
858 | // | |
859 | /// The 32-bit signed integer type. | |
32a655c1 | 860 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 861 | mod prim_i32 {} |
c1a9b12d SL |
862 | |
863 | #[doc(primitive = "i64")] | |
864 | // | |
865 | /// The 64-bit signed integer type. | |
32a655c1 | 866 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 867 | mod prim_i64 {} |
c1a9b12d | 868 | |
32a655c1 SL |
869 | #[doc(primitive = "i128")] |
870 | // | |
871 | /// The 128-bit signed integer type. | |
dfeec247 XL |
872 | #[stable(feature = "i128", since = "1.26.0")] |
873 | mod prim_i128 {} | |
32a655c1 | 874 | |
c1a9b12d SL |
875 | #[doc(primitive = "u8")] |
876 | // | |
877 | /// The 8-bit unsigned integer type. | |
32a655c1 | 878 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 879 | mod prim_u8 {} |
c1a9b12d SL |
880 | |
881 | #[doc(primitive = "u16")] | |
882 | // | |
883 | /// The 16-bit unsigned integer type. | |
32a655c1 | 884 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 885 | mod prim_u16 {} |
c1a9b12d SL |
886 | |
887 | #[doc(primitive = "u32")] | |
888 | // | |
889 | /// The 32-bit unsigned integer type. | |
32a655c1 | 890 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 891 | mod prim_u32 {} |
c1a9b12d SL |
892 | |
893 | #[doc(primitive = "u64")] | |
894 | // | |
895 | /// The 64-bit unsigned integer type. | |
32a655c1 | 896 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 897 | mod prim_u64 {} |
c1a9b12d | 898 | |
32a655c1 SL |
899 | #[doc(primitive = "u128")] |
900 | // | |
901 | /// The 128-bit unsigned integer type. | |
dfeec247 XL |
902 | #[stable(feature = "i128", since = "1.26.0")] |
903 | mod prim_u128 {} | |
32a655c1 | 904 | |
c1a9b12d SL |
905 | #[doc(primitive = "isize")] |
906 | // | |
907 | /// The pointer-sized signed integer type. | |
908 | /// | |
ea8adc8c XL |
909 | /// The size of this primitive is how many bytes it takes to reference any |
910 | /// location in memory. For example, on a 32 bit target, this is 4 bytes | |
911 | /// and on a 64 bit target, this is 8 bytes. | |
32a655c1 | 912 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 913 | mod prim_isize {} |
c1a9b12d SL |
914 | |
915 | #[doc(primitive = "usize")] | |
916 | // | |
b039eaaf | 917 | /// The pointer-sized unsigned integer type. |
c1a9b12d | 918 | /// |
ea8adc8c XL |
919 | /// The size of this primitive is how many bytes it takes to reference any |
920 | /// location in memory. For example, on a 32 bit target, this is 4 bytes | |
921 | /// and on a 64 bit target, this is 8 bytes. | |
32a655c1 | 922 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 923 | mod prim_usize {} |
3b2f2976 XL |
924 | |
925 | #[doc(primitive = "reference")] | |
83c7162d | 926 | #[doc(alias = "&")] |
fc512014 | 927 | #[doc(alias = "&mut")] |
3b2f2976 XL |
928 | // |
929 | /// References, both shared and mutable. | |
930 | /// | |
931 | /// A reference represents a borrow of some owned value. You can get one by using the `&` or `&mut` | |
932 | /// operators on a value, or by using a `ref` or `ref mut` pattern. | |
933 | /// | |
416331ca XL |
934 | /// For those familiar with pointers, a reference is just a pointer that is assumed to be |
935 | /// aligned, not null, and pointing to memory containing a valid value of `T` - for example, | |
936 | /// `&bool` can only point to an allocation containing the integer values `1` (`true`) or `0` | |
937 | /// (`false`), but creating a `&bool` that points to an allocation containing | |
938 | /// the value `3` causes undefined behaviour. | |
939 | /// In fact, `Option<&T>` has the same memory representation as a | |
940 | /// nullable but aligned pointer, and can be passed across FFI boundaries as such. | |
3b2f2976 XL |
941 | /// |
942 | /// In most cases, references can be used much like the original value. Field access, method | |
943 | /// calling, and indexing work the same (save for mutability rules, of course). In addition, the | |
944 | /// comparison operators transparently defer to the referent's implementation, allowing references | |
945 | /// to be compared the same as owned values. | |
946 | /// | |
947 | /// References have a lifetime attached to them, which represents the scope for which the borrow is | |
948 | /// valid. A lifetime is said to "outlive" another one if its representative scope is as long or | |
949 | /// longer than the other. The `'static` lifetime is the longest lifetime, which represents the | |
950 | /// total life of the program. For example, string literals have a `'static` lifetime because the | |
951 | /// text data is embedded into the binary of the program, rather than in an allocation that needs | |
952 | /// to be dynamically managed. | |
953 | /// | |
954 | /// `&mut T` references can be freely coerced into `&T` references with the same referent type, and | |
955 | /// references with longer lifetimes can be freely coerced into references with shorter ones. | |
956 | /// | |
0bf4aa26 XL |
957 | /// Reference equality by address, instead of comparing the values pointed to, is accomplished via |
958 | /// implicit reference-pointer coercion and raw pointer equality via [`ptr::eq`], while | |
959 | /// [`PartialEq`] compares values. | |
960 | /// | |
0bf4aa26 XL |
961 | /// ``` |
962 | /// use std::ptr; | |
963 | /// | |
964 | /// let five = 5; | |
965 | /// let other_five = 5; | |
966 | /// let five_ref = &five; | |
967 | /// let same_five_ref = &five; | |
968 | /// let other_five_ref = &other_five; | |
969 | /// | |
970 | /// assert!(five_ref == same_five_ref); | |
971 | /// assert!(five_ref == other_five_ref); | |
972 | /// | |
973 | /// assert!(ptr::eq(five_ref, same_five_ref)); | |
974 | /// assert!(!ptr::eq(five_ref, other_five_ref)); | |
975 | /// ``` | |
976 | /// | |
3b2f2976 XL |
977 | /// For more information on how to use references, see [the book's section on "References and |
978 | /// Borrowing"][book-refs]. | |
979 | /// | |
0731742a | 980 | /// [book-refs]: ../book/ch04-02-references-and-borrowing.html |
3b2f2976 | 981 | /// |
0bf4aa26 XL |
982 | /// # Trait implementations |
983 | /// | |
3b2f2976 XL |
984 | /// The following traits are implemented for all `&T`, regardless of the type of its referent: |
985 | /// | |
986 | /// * [`Copy`] | |
987 | /// * [`Clone`] \(Note that this will not defer to `T`'s `Clone` implementation if it exists!) | |
988 | /// * [`Deref`] | |
989 | /// * [`Borrow`] | |
990 | /// * [`Pointer`] | |
991 | /// | |
1b1a35ee XL |
992 | /// [`Deref`]: ops::Deref |
993 | /// [`Borrow`]: borrow::Borrow | |
994 | /// [`Pointer`]: fmt::Pointer | |
3b2f2976 XL |
995 | /// |
996 | /// `&mut T` references get all of the above except `Copy` and `Clone` (to prevent creating | |
997 | /// multiple simultaneous mutable borrows), plus the following, regardless of the type of its | |
998 | /// referent: | |
999 | /// | |
1000 | /// * [`DerefMut`] | |
1001 | /// * [`BorrowMut`] | |
1002 | /// | |
1b1a35ee XL |
1003 | /// [`DerefMut`]: ops::DerefMut |
1004 | /// [`BorrowMut`]: borrow::BorrowMut | |
3b2f2976 XL |
1005 | /// |
1006 | /// The following traits are implemented on `&T` references if the underlying `T` also implements | |
1007 | /// that trait: | |
1008 | /// | |
1009 | /// * All the traits in [`std::fmt`] except [`Pointer`] and [`fmt::Write`] | |
1010 | /// * [`PartialOrd`] | |
1011 | /// * [`Ord`] | |
1012 | /// * [`PartialEq`] | |
1013 | /// * [`Eq`] | |
1014 | /// * [`AsRef`] | |
1015 | /// * [`Fn`] \(in addition, `&T` references get [`FnMut`] and [`FnOnce`] if `T: Fn`) | |
1016 | /// * [`Hash`] | |
1017 | /// * [`ToSocketAddrs`] | |
1018 | /// | |
1b1a35ee XL |
1019 | /// [`std::fmt`]: fmt |
1020 | /// ['Pointer`]: fmt::Pointer | |
1021 | /// [`Hash`]: hash::Hash | |
1022 | /// [`ToSocketAddrs`]: net::ToSocketAddrs | |
3b2f2976 XL |
1023 | /// |
1024 | /// `&mut T` references get all of the above except `ToSocketAddrs`, plus the following, if `T` | |
1025 | /// implements that trait: | |
1026 | /// | |
1027 | /// * [`AsMut`] | |
1028 | /// * [`FnMut`] \(in addition, `&mut T` references get [`FnOnce`] if `T: FnMut`) | |
1029 | /// * [`fmt::Write`] | |
1030 | /// * [`Iterator`] | |
1031 | /// * [`DoubleEndedIterator`] | |
1032 | /// * [`ExactSizeIterator`] | |
1033 | /// * [`FusedIterator`] | |
1034 | /// * [`TrustedLen`] | |
1035 | /// * [`Send`] \(note that `&T` references only get `Send` if `T: Sync`) | |
1036 | /// * [`io::Write`] | |
1037 | /// * [`Read`] | |
1038 | /// * [`Seek`] | |
1039 | /// * [`BufRead`] | |
1040 | /// | |
1b1a35ee XL |
1041 | /// [`FusedIterator`]: iter::FusedIterator |
1042 | /// [`TrustedLen`]: iter::TrustedLen | |
1043 | /// [`Seek`]: io::Seek | |
1044 | /// [`BufRead`]: io::BufRead | |
1045 | /// [`Read`]: io::Read | |
3b2f2976 XL |
1046 | /// |
1047 | /// Note that due to method call deref coercion, simply calling a trait method will act like they | |
1048 | /// work on references as well as they do on owned values! The implementations described here are | |
1049 | /// meant for generic contexts, where the final type `T` is a type parameter or otherwise not | |
1050 | /// locally known. | |
1051 | #[stable(feature = "rust1", since = "1.0.0")] | |
dfeec247 | 1052 | mod prim_ref {} |
3b2f2976 XL |
1053 | |
1054 | #[doc(primitive = "fn")] | |
1055 | // | |
1056 | /// Function pointers, like `fn(usize) -> bool`. | |
1057 | /// | |
1058 | /// *See also the traits [`Fn`], [`FnMut`], and [`FnOnce`].* | |
1059 | /// | |
1b1a35ee XL |
1060 | /// [`Fn`]: ops::Fn |
1061 | /// [`FnMut`]: ops::FnMut | |
1062 | /// [`FnOnce`]: ops::FnOnce | |
3b2f2976 | 1063 | /// |
416331ca XL |
1064 | /// Function pointers are pointers that point to *code*, not data. They can be called |
1065 | /// just like functions. Like references, function pointers are, among other things, assumed to | |
1066 | /// not be null, so if you want to pass a function pointer over FFI and be able to accommodate null | |
1067 | /// pointers, make your type `Option<fn()>` with your required signature. | |
1068 | /// | |
3dfed10e XL |
1069 | /// ### Safety |
1070 | /// | |
3b2f2976 XL |
1071 | /// Plain function pointers are obtained by casting either plain functions, or closures that don't |
1072 | /// capture an environment: | |
1073 | /// | |
1074 | /// ``` | |
1075 | /// fn add_one(x: usize) -> usize { | |
1076 | /// x + 1 | |
1077 | /// } | |
1078 | /// | |
1079 | /// let ptr: fn(usize) -> usize = add_one; | |
1080 | /// assert_eq!(ptr(5), 6); | |
1081 | /// | |
1082 | /// let clos: fn(usize) -> usize = |x| x + 5; | |
1083 | /// assert_eq!(clos(5), 10); | |
1084 | /// ``` | |
1085 | /// | |
1086 | /// In addition to varying based on their signature, function pointers come in two flavors: safe | |
1087 | /// and unsafe. Plain `fn()` function pointers can only point to safe functions, | |
1088 | /// while `unsafe fn()` function pointers can point to safe or unsafe functions. | |
1089 | /// | |
1090 | /// ``` | |
1091 | /// fn add_one(x: usize) -> usize { | |
1092 | /// x + 1 | |
1093 | /// } | |
1094 | /// | |
1095 | /// unsafe fn add_one_unsafely(x: usize) -> usize { | |
1096 | /// x + 1 | |
1097 | /// } | |
1098 | /// | |
1099 | /// let safe_ptr: fn(usize) -> usize = add_one; | |
1100 | /// | |
1101 | /// //ERROR: mismatched types: expected normal fn, found unsafe fn | |
1102 | /// //let bad_ptr: fn(usize) -> usize = add_one_unsafely; | |
1103 | /// | |
1104 | /// let unsafe_ptr: unsafe fn(usize) -> usize = add_one_unsafely; | |
1105 | /// let really_safe_ptr: unsafe fn(usize) -> usize = add_one; | |
1106 | /// ``` | |
1107 | /// | |
3dfed10e XL |
1108 | /// ### ABI |
1109 | /// | |
1110 | /// On top of that, function pointers can vary based on what ABI they use. This | |
1111 | /// is achieved by adding the `extern` keyword before the type, followed by the | |
1112 | /// ABI in question. The default ABI is "Rust", i.e., `fn()` is the exact same | |
1113 | /// type as `extern "Rust" fn()`. A pointer to a function with C ABI would have | |
1114 | /// type `extern "C" fn()`. | |
1115 | /// | |
1116 | /// `extern "ABI" { ... }` blocks declare functions with ABI "ABI". The default | |
1117 | /// here is "C", i.e., functions declared in an `extern {...}` block have "C" | |
1118 | /// ABI. | |
3b2f2976 | 1119 | /// |
3dfed10e XL |
1120 | /// For more information and a list of supported ABIs, see [the nomicon's |
1121 | /// section on foreign calling conventions][nomicon-abi]. | |
1122 | /// | |
29967ef6 XL |
1123 | /// [nomicon-abi]: ../nomicon/ffi.html#foreign-calling-conventions |
1124 | /// | |
3dfed10e | 1125 | /// ### Variadic functions |
3b2f2976 XL |
1126 | /// |
1127 | /// Extern function declarations with the "C" or "cdecl" ABIs can also be *variadic*, allowing them | |
3dfed10e | 1128 | /// to be called with a variable number of arguments. Normal Rust functions, even those with an |
3b2f2976 XL |
1129 | /// `extern "ABI"`, cannot be variadic. For more information, see [the nomicon's section on |
1130 | /// variadic functions][nomicon-variadic]. | |
1131 | /// | |
1132 | /// [nomicon-variadic]: ../nomicon/ffi.html#variadic-functions | |
1133 | /// | |
3dfed10e XL |
1134 | /// ### Creating function pointers |
1135 | /// | |
1136 | /// When `bar` is the name of a function, then the expression `bar` is *not* a | |
1137 | /// function pointer. Rather, it denotes a value of an unnameable type that | |
1138 | /// uniquely identifies the function `bar`. The value is zero-sized because the | |
1139 | /// type already identifies the function. This has the advantage that "calling" | |
1140 | /// the value (it implements the `Fn*` traits) does not require dynamic | |
1141 | /// dispatch. | |
1142 | /// | |
1143 | /// This zero-sized type *coerces* to a regular function pointer. For example: | |
1144 | /// | |
1145 | /// ```rust | |
1146 | /// use std::mem; | |
1147 | /// | |
1148 | /// fn bar(x: i32) {} | |
1149 | /// | |
1150 | /// let not_bar_ptr = bar; // `not_bar_ptr` is zero-sized, uniquely identifying `bar` | |
1151 | /// assert_eq!(mem::size_of_val(¬_bar_ptr), 0); | |
1152 | /// | |
1153 | /// let bar_ptr: fn(i32) = not_bar_ptr; // force coercion to function pointer | |
1154 | /// assert_eq!(mem::size_of_val(&bar_ptr), mem::size_of::<usize>()); | |
1155 | /// | |
1156 | /// let footgun = &bar; // this is a shared reference to the zero-sized type identifying `bar` | |
1157 | /// ``` | |
1158 | /// | |
1159 | /// The last line shows that `&bar` is not a function pointer either. Rather, it | |
1160 | /// is a reference to the function-specific ZST. `&bar` is basically never what you | |
1161 | /// want when `bar` is a function. | |
1162 | /// | |
1163 | /// ### Traits | |
3b2f2976 | 1164 | /// |
3b2f2976 XL |
1165 | /// Function pointers implement the following traits: |
1166 | /// | |
1167 | /// * [`Clone`] | |
1168 | /// * [`PartialEq`] | |
1169 | /// * [`Eq`] | |
1170 | /// * [`PartialOrd`] | |
1171 | /// * [`Ord`] | |
1172 | /// * [`Hash`] | |
1173 | /// * [`Pointer`] | |
1174 | /// * [`Debug`] | |
1175 | /// | |
1b1a35ee XL |
1176 | /// [`Hash`]: hash::Hash |
1177 | /// [`Pointer`]: fmt::Pointer | |
3b2f2976 XL |
1178 | /// |
1179 | /// Due to a temporary restriction in Rust's type system, these traits are only implemented on | |
1180 | /// functions that take 12 arguments or less, with the `"Rust"` and `"C"` ABIs. In the future, this | |
1181 | /// may change. | |
1182 | /// | |
1183 | /// In addition, function pointers of *any* signature, ABI, or safety are [`Copy`], and all *safe* | |
1184 | /// function pointers implement [`Fn`], [`FnMut`], and [`FnOnce`]. This works because these traits | |
1185 | /// are specially known to the compiler. | |
3b2f2976 | 1186 | #[stable(feature = "rust1", since = "1.0.0")] |
dfeec247 | 1187 | mod prim_fn {} |