core/mem/mod.rs
1//! Basic functions for dealing with memory.
2//!
3//! This module contains functions for querying the size and alignment of
4//! types, initializing and manipulating memory.
5
6#![stable(feature = "rust1", since = "1.0.0")]
7
8use crate::alloc::Layout;
9#[cfg(not(feature = "ferrocene_subset"))]
10use crate::clone::TrivialClone;
11use crate::marker::{Destruct, DiscriminantKind};
12use crate::panic::const_assert;
13#[cfg(not(feature = "ferrocene_subset"))]
14use crate::{clone, cmp, fmt, hash, intrinsics, ptr};
15
16// Ferrocene addition: imports for certified subset
17#[cfg(feature = "ferrocene_subset")]
18#[rustfmt::skip]
19use crate::{cmp, intrinsics, ptr};
20
21mod manually_drop;
22#[stable(feature = "manually_drop", since = "1.20.0")]
23pub use manually_drop::ManuallyDrop;
24
25mod maybe_uninit;
26#[stable(feature = "maybe_uninit", since = "1.36.0")]
27pub use maybe_uninit::MaybeUninit;
28
29#[cfg(not(feature = "ferrocene_subset"))]
30mod transmutability;
31#[unstable(feature = "transmutability", issue = "99571")]
32#[cfg(not(feature = "ferrocene_subset"))]
33pub use transmutability::{Assume, TransmuteFrom};
34
35#[cfg(not(feature = "ferrocene_subset"))]
36mod drop_guard;
37#[unstable(feature = "drop_guard", issue = "144426")]
38#[cfg(not(feature = "ferrocene_subset"))]
39pub use drop_guard::DropGuard;
40
41// This one has to be a re-export (rather than wrapping the underlying intrinsic) so that we can do
42// the special magic "types have equal size" check at the call site.
43#[stable(feature = "rust1", since = "1.0.0")]
44#[doc(inline)]
45pub use crate::intrinsics::transmute;
46
47/// Takes ownership and "forgets" about the value **without running its destructor**.
48///
49/// Any resources the value manages, such as heap memory or a file handle, will linger
50/// forever in an unreachable state. However, it does not guarantee that pointers
51/// to this memory will remain valid.
52///
53/// * If you want to leak memory, see [`Box::leak`].
54/// * If you want to obtain a raw pointer to the memory, see [`Box::into_raw`].
55/// * If you want to dispose of a value properly, running its destructor, see
56/// [`mem::drop`].
57///
58/// # Safety
59///
60/// `forget` is not marked as `unsafe`, because Rust's safety guarantees
61/// do not include a guarantee that destructors will always run. For example,
62/// a program can create a reference cycle using [`Rc`][rc], or call
63/// [`process::exit`][exit] to exit without running destructors. Thus, allowing
64/// `mem::forget` from safe code does not fundamentally change Rust's safety
65/// guarantees.
66///
67/// That said, leaking resources such as memory or I/O objects is usually undesirable.
68/// The need comes up in some specialized use cases for FFI or unsafe code, but even
69/// then, [`ManuallyDrop`] is typically preferred.
70///
71/// Because forgetting a value is allowed, any `unsafe` code you write must
72/// allow for this possibility. You cannot return a value and expect that the
73/// caller will necessarily run the value's destructor.
74///
75/// [rc]: ../../std/rc/struct.Rc.html
76/// [exit]: ../../std/process/fn.exit.html
77///
78/// # Examples
79///
80/// The canonical safe use of `mem::forget` is to circumvent a value's destructor
81/// implemented by the `Drop` trait. For example, this will leak a `File`, i.e. reclaim
82/// the space taken by the variable but never close the underlying system resource:
83///
84/// ```no_run
85/// use std::mem;
86/// use std::fs::File;
87///
88/// let file = File::open("foo.txt").unwrap();
89/// mem::forget(file);
90/// ```
91///
92/// This is useful when the ownership of the underlying resource was previously
93/// transferred to code outside of Rust, for example by transmitting the raw
94/// file descriptor to C code.
95///
96/// # Relationship with `ManuallyDrop`
97///
98/// While `mem::forget` can also be used to transfer *memory* ownership, doing so is error-prone.
99/// [`ManuallyDrop`] should be used instead. Consider, for example, this code:
100///
101/// ```
102/// use std::mem;
103///
104/// let mut v = vec![65, 122];
105/// // Build a `String` using the contents of `v`
106/// let s = unsafe { String::from_raw_parts(v.as_mut_ptr(), v.len(), v.capacity()) };
107/// // leak `v` because its memory is now managed by `s`
108/// mem::forget(v); // ERROR - v is invalid and must not be passed to a function
109/// assert_eq!(s, "Az");
110/// // `s` is implicitly dropped and its memory deallocated.
111/// ```
112///
113/// There are two issues with the above example:
114///
115/// * If more code were added between the construction of `String` and the invocation of
116/// `mem::forget()`, a panic within it would cause a double free because the same memory
117/// is handled by both `v` and `s`.
118/// * After calling `v.as_mut_ptr()` and transmitting the ownership of the data to `s`,
119/// the `v` value is invalid. Even when a value is just moved to `mem::forget` (which won't
120/// inspect it), some types have strict requirements on their values that
121/// make them invalid when dangling or no longer owned. Using invalid values in any
122/// way, including passing them to or returning them from functions, constitutes
123/// undefined behavior and may break the assumptions made by the compiler.
124///
125/// Switching to `ManuallyDrop` avoids both issues:
126///
127/// ```
128/// use std::mem::ManuallyDrop;
129///
130/// let v = vec![65, 122];
131/// // Before we disassemble `v` into its raw parts, make sure it
132/// // does not get dropped!
133/// let mut v = ManuallyDrop::new(v);
134/// // Now disassemble `v`. These operations cannot panic, so there cannot be a leak.
135/// let (ptr, len, cap) = (v.as_mut_ptr(), v.len(), v.capacity());
136/// // Finally, build a `String`.
137/// let s = unsafe { String::from_raw_parts(ptr, len, cap) };
138/// assert_eq!(s, "Az");
139/// // `s` is implicitly dropped and its memory deallocated.
140/// ```
141///
142/// `ManuallyDrop` robustly prevents double-free because we disable `v`'s destructor
143/// before doing anything else. `mem::forget()` doesn't allow this because it consumes its
144/// argument, forcing us to call it only after extracting anything we need from `v`. Even
145/// if a panic were introduced between construction of `ManuallyDrop` and building the
146/// string (which cannot happen in the code as shown), it would result in a leak and not a
147/// double free. In other words, `ManuallyDrop` errs on the side of leaking instead of
148/// erring on the side of (double-)dropping.
149///
150/// Also, `ManuallyDrop` prevents us from having to "touch" `v` after transferring the
151/// ownership to `s` — the final step of interacting with `v` to dispose of it without
152/// running its destructor is entirely avoided.
153///
154/// [`Box`]: ../../std/boxed/struct.Box.html
155/// [`Box::leak`]: ../../std/boxed/struct.Box.html#method.leak
156/// [`Box::into_raw`]: ../../std/boxed/struct.Box.html#method.into_raw
157/// [`mem::drop`]: drop
158/// [ub]: ../../reference/behavior-considered-undefined.html
159#[inline]
160#[rustc_const_stable(feature = "const_forget", since = "1.46.0")]
161#[stable(feature = "rust1", since = "1.0.0")]
162#[rustc_diagnostic_item = "mem_forget"]
163pub const fn forget<T>(t: T) {
164 let _ = ManuallyDrop::new(t);
165}
166
167/// Like [`forget`], but also accepts unsized values.
168///
169/// While Rust does not permit unsized locals since its removal in [#111942] it is
170/// still possible to call functions with unsized values from a function argument
171/// or place expression.
172///
173/// ```rust
174/// #![feature(unsized_fn_params, forget_unsized)]
175/// #![allow(internal_features)]
176///
177/// use std::mem::forget_unsized;
178///
179/// pub fn in_place() {
180/// forget_unsized(*Box::<str>::from("str"));
181/// }
182///
183/// pub fn param(x: str) {
184/// forget_unsized(x);
185/// }
186/// ```
187///
188/// This works because the compiler will alter these functions to pass the parameter
189/// by reference instead. This trick is necessary to support `Box<dyn FnOnce()>: FnOnce()`.
190/// See [#68304] and [#71170] for more information.
191///
192/// [#111942]: https://github.com/rust-lang/rust/issues/111942
193/// [#68304]: https://github.com/rust-lang/rust/issues/68304
194/// [#71170]: https://github.com/rust-lang/rust/pull/71170
195#[inline]
196#[unstable(feature = "forget_unsized", issue = "none")]
197#[cfg(not(feature = "ferrocene_subset"))]
198pub fn forget_unsized<T: ?Sized>(t: T) {
199 intrinsics::forget(t)
200}
201
202/// Returns the size of a type in bytes.
203///
204/// More specifically, this is the offset in bytes between successive elements
205/// in an array with that item type including alignment padding. Thus, for any
206/// type `T` and length `n`, `[T; n]` has a size of `n * size_of::<T>()`.
207///
208/// In general, the size of a type is not stable across compilations, but
209/// specific types such as primitives are.
210///
211/// The following table gives the size for primitives.
212///
213/// Type | `size_of::<Type>()`
214/// ---- | ---------------
215/// () | 0
216/// bool | 1
217/// u8 | 1
218/// u16 | 2
219/// u32 | 4
220/// u64 | 8
221/// u128 | 16
222/// i8 | 1
223/// i16 | 2
224/// i32 | 4
225/// i64 | 8
226/// i128 | 16
227/// f32 | 4
228/// f64 | 8
229/// char | 4
230///
231/// Furthermore, `usize` and `isize` have the same size.
232///
233/// The types [`*const T`], `&T`, [`Box<T>`], [`Option<&T>`], and `Option<Box<T>>` all have
234/// the same size. If `T` is `Sized`, all of those types have the same size as `usize`.
235///
236/// The mutability of a pointer does not change its size. As such, `&T` and `&mut T`
237/// have the same size. Likewise for `*const T` and `*mut T`.
238///
239/// # Size of `#[repr(C)]` items
240///
241/// The `C` representation for items has a defined layout. With this layout,
242/// the size of items is also stable as long as all fields have a stable size.
243///
244/// ## Size of Structs
245///
246/// For `struct`s, the size is determined by the following algorithm.
247///
248/// For each field in the struct ordered by declaration order:
249///
250/// 1. Add the size of the field.
251/// 2. Round up the current size to the nearest multiple of the next field's [alignment].
252///
253/// Finally, round the size of the struct to the nearest multiple of its [alignment].
254/// The alignment of the struct is usually the largest alignment of all its
255/// fields; this can be changed with the use of `repr(align(N))`.
256///
257/// Unlike `C`, zero sized structs are not rounded up to one byte in size.
258///
259/// ## Size of Enums
260///
261/// Enums that carry no data other than the discriminant have the same size as C enums
262/// on the platform they are compiled for.
263///
264/// ## Size of Unions
265///
266/// The size of a union is the size of its largest field.
267///
268/// Unlike `C`, zero sized unions are not rounded up to one byte in size.
269///
270/// # Examples
271///
272/// ```
273/// // Some primitives
274/// assert_eq!(4, size_of::<i32>());
275/// assert_eq!(8, size_of::<f64>());
276/// assert_eq!(0, size_of::<()>());
277///
278/// // Some arrays
279/// assert_eq!(8, size_of::<[i32; 2]>());
280/// assert_eq!(12, size_of::<[i32; 3]>());
281/// assert_eq!(0, size_of::<[i32; 0]>());
282///
283///
284/// // Pointer size equality
285/// assert_eq!(size_of::<&i32>(), size_of::<*const i32>());
286/// assert_eq!(size_of::<&i32>(), size_of::<Box<i32>>());
287/// assert_eq!(size_of::<&i32>(), size_of::<Option<&i32>>());
288/// assert_eq!(size_of::<Box<i32>>(), size_of::<Option<Box<i32>>>());
289/// ```
290///
291/// Using `#[repr(C)]`.
292///
293/// ```
294/// #[repr(C)]
295/// struct FieldStruct {
296/// first: u8,
297/// second: u16,
298/// third: u8
299/// }
300///
301/// // The size of the first field is 1, so add 1 to the size. Size is 1.
302/// // The alignment of the second field is 2, so add 1 to the size for padding. Size is 2.
303/// // The size of the second field is 2, so add 2 to the size. Size is 4.
304/// // The alignment of the third field is 1, so add 0 to the size for padding. Size is 4.
305/// // The size of the third field is 1, so add 1 to the size. Size is 5.
306/// // Finally, the alignment of the struct is 2 (because the largest alignment amongst its
307/// // fields is 2), so add 1 to the size for padding. Size is 6.
308/// assert_eq!(6, size_of::<FieldStruct>());
309///
310/// #[repr(C)]
311/// struct TupleStruct(u8, u16, u8);
312///
313/// // Tuple structs follow the same rules.
314/// assert_eq!(6, size_of::<TupleStruct>());
315///
316/// // Note that reordering the fields can lower the size. We can remove both padding bytes
317/// // by putting `third` before `second`.
318/// #[repr(C)]
319/// struct FieldStructOptimized {
320/// first: u8,
321/// third: u8,
322/// second: u16
323/// }
324///
325/// assert_eq!(4, size_of::<FieldStructOptimized>());
326///
327/// // Union size is the size of the largest field.
328/// #[repr(C)]
329/// union ExampleUnion {
330/// smaller: u8,
331/// larger: u16
332/// }
333///
334/// assert_eq!(2, size_of::<ExampleUnion>());
335/// ```
336///
337/// [alignment]: align_of
338/// [`*const T`]: primitive@pointer
339/// [`Box<T>`]: ../../std/boxed/struct.Box.html
340/// [`Option<&T>`]: crate::option::Option
341///
342#[inline(always)]
343#[must_use]
344#[stable(feature = "rust1", since = "1.0.0")]
345#[rustc_promotable]
346#[rustc_const_stable(feature = "const_mem_size_of", since = "1.24.0")]
347#[rustc_diagnostic_item = "mem_size_of"]
348pub const fn size_of<T>() -> usize {
349 <T as SizedTypeProperties>::SIZE
350}
351
352/// Returns the size of the pointed-to value in bytes.
353///
354/// This is usually the same as [`size_of::<T>()`]. However, when `T` *has* no
355/// statically-known size, e.g., a slice [`[T]`][slice] or a [trait object],
356/// then `size_of_val` can be used to get the dynamically-known size.
357///
358/// [trait object]: ../../book/ch17-02-trait-objects.html
359///
360/// # Examples
361///
362/// ```
363/// assert_eq!(4, size_of_val(&5i32));
364///
365/// let x: [u8; 13] = [0; 13];
366/// let y: &[u8] = &x;
367/// assert_eq!(13, size_of_val(y));
368/// ```
369///
370/// [`size_of::<T>()`]: size_of
371#[inline]
372#[must_use]
373#[stable(feature = "rust1", since = "1.0.0")]
374#[rustc_const_stable(feature = "const_size_of_val", since = "1.85.0")]
375#[rustc_diagnostic_item = "mem_size_of_val"]
376pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
377 // SAFETY: `val` is a reference, so it's a valid raw pointer
378 unsafe { intrinsics::size_of_val(val) }
379}
380
381/// Returns the size of the pointed-to value in bytes.
382///
383/// This is usually the same as [`size_of::<T>()`]. However, when `T` *has* no
384/// statically-known size, e.g., a slice [`[T]`][slice] or a [trait object],
385/// then `size_of_val_raw` can be used to get the dynamically-known size.
386///
387/// # Safety
388///
389/// This function is only safe to call if the following conditions hold:
390///
391/// - If `T` is `Sized`, this function is always safe to call.
392/// - If the unsized tail of `T` is:
393/// - a [slice], then the length of the slice tail must be an initialized
394/// integer, and the size of the *entire value*
395/// (dynamic tail length + statically sized prefix) must fit in `isize`.
396/// For the special case where the dynamic tail length is 0, this function
397/// is safe to call.
398// NOTE: the reason this is safe is that if an overflow were to occur already with size 0,
399// then we would stop compilation as even the "statically known" part of the type would
400// already be too big (or the call may be in dead code and optimized away, but then it
401// doesn't matter).
402/// - a [trait object], then the vtable part of the pointer must point
403/// to a valid vtable acquired by an unsizing coercion, and the size
404/// of the *entire value* (dynamic tail length + statically sized prefix)
405/// must fit in `isize`.
406/// - an (unstable) [extern type], then this function is always safe to
407/// call, but may panic or otherwise return the wrong value, as the
408/// extern type's layout is not known. This is the same behavior as
409/// [`size_of_val`] on a reference to a type with an extern type tail.
410/// - otherwise, it is conservatively not allowed to call this function.
411///
412/// [`size_of::<T>()`]: size_of
413/// [trait object]: ../../book/ch17-02-trait-objects.html
414/// [extern type]: ../../unstable-book/language-features/extern-types.html
415///
416/// # Examples
417///
418/// ```
419/// #![feature(layout_for_ptr)]
420/// use std::mem;
421///
422/// assert_eq!(4, size_of_val(&5i32));
423///
424/// let x: [u8; 13] = [0; 13];
425/// let y: &[u8] = &x;
426/// assert_eq!(13, unsafe { mem::size_of_val_raw(y) });
427/// ```
428#[inline]
429#[must_use]
430#[unstable(feature = "layout_for_ptr", issue = "69835")]
431pub const unsafe fn size_of_val_raw<T: ?Sized>(val: *const T) -> usize {
432 // SAFETY: the caller must provide a valid raw pointer
433 unsafe { intrinsics::size_of_val(val) }
434}
435
436/// Returns the [ABI]-required minimum alignment of a type in bytes.
437///
438/// Every reference to a value of the type `T` must be a multiple of this number.
439///
440/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
441///
442/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
443///
444/// # Examples
445///
446/// ```
447/// # #![allow(deprecated)]
448/// use std::mem;
449///
450/// assert_eq!(4, mem::min_align_of::<i32>());
451/// ```
452#[inline]
453#[must_use]
454#[stable(feature = "rust1", since = "1.0.0")]
455#[deprecated(note = "use `align_of` instead", since = "1.2.0", suggestion = "align_of")]
456#[cfg(not(feature = "ferrocene_subset"))]
457pub fn min_align_of<T>() -> usize {
458 <T as SizedTypeProperties>::ALIGN
459}
460
461/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in
462/// bytes.
463///
464/// Every reference to a value of the type `T` must be a multiple of this number.
465///
466/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
467///
468/// # Examples
469///
470/// ```
471/// # #![allow(deprecated)]
472/// use std::mem;
473///
474/// assert_eq!(4, mem::min_align_of_val(&5i32));
475/// ```
476#[inline]
477#[must_use]
478#[stable(feature = "rust1", since = "1.0.0")]
479#[deprecated(note = "use `align_of_val` instead", since = "1.2.0", suggestion = "align_of_val")]
480#[cfg(not(feature = "ferrocene_subset"))]
481pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
482 // SAFETY: val is a reference, so it's a valid raw pointer
483 unsafe { intrinsics::align_of_val(val) }
484}
485
486/// Returns the [ABI]-required minimum alignment of a type in bytes.
487///
488/// Every reference to a value of the type `T` must be a multiple of this number.
489///
490/// This is the alignment used for struct fields. It may be smaller than the preferred alignment.
491///
492/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
493///
494/// # Examples
495///
496/// ```
497/// assert_eq!(4, align_of::<i32>());
498/// ```
499#[inline(always)]
500#[must_use]
501#[stable(feature = "rust1", since = "1.0.0")]
502#[rustc_promotable]
503#[rustc_const_stable(feature = "const_align_of", since = "1.24.0")]
504#[rustc_diagnostic_item = "mem_align_of"]
505pub const fn align_of<T>() -> usize {
506 <T as SizedTypeProperties>::ALIGN
507}
508
509/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in
510/// bytes.
511///
512/// Every reference to a value of the type `T` must be a multiple of this number.
513///
514/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
515///
516/// # Examples
517///
518/// ```
519/// assert_eq!(4, align_of_val(&5i32));
520/// ```
521#[inline]
522#[must_use]
523#[stable(feature = "rust1", since = "1.0.0")]
524#[rustc_const_stable(feature = "const_align_of_val", since = "1.85.0")]
525pub const fn align_of_val<T: ?Sized>(val: &T) -> usize {
526 // SAFETY: val is a reference, so it's a valid raw pointer
527 unsafe { intrinsics::align_of_val(val) }
528}
529
530/// Returns the [ABI]-required minimum alignment of the type of the value that `val` points to in
531/// bytes.
532///
533/// Every reference to a value of the type `T` must be a multiple of this number.
534///
535/// [ABI]: https://en.wikipedia.org/wiki/Application_binary_interface
536///
537/// # Safety
538///
539/// This function is only safe to call if the following conditions hold:
540///
541/// - If `T` is `Sized`, this function is always safe to call.
542/// - If the unsized tail of `T` is:
543/// - a [slice], then the length of the slice tail must be an initialized
544/// integer, and the size of the *entire value*
545/// (dynamic tail length + statically sized prefix) must fit in `isize`.
546/// For the special case where the dynamic tail length is 0, this function
547/// is safe to call.
548/// - a [trait object], then the vtable part of the pointer must point
549/// to a valid vtable acquired by an unsizing coercion, and the size
550/// of the *entire value* (dynamic tail length + statically sized prefix)
551/// must fit in `isize`.
552/// - an (unstable) [extern type], then this function is always safe to
553/// call, but may panic or otherwise return the wrong value, as the
554/// extern type's layout is not known. This is the same behavior as
555/// [`align_of_val`] on a reference to a type with an extern type tail.
556/// - otherwise, it is conservatively not allowed to call this function.
557///
558/// [trait object]: ../../book/ch17-02-trait-objects.html
559/// [extern type]: ../../unstable-book/language-features/extern-types.html
560///
561/// # Examples
562///
563/// ```
564/// #![feature(layout_for_ptr)]
565/// use std::mem;
566///
567/// assert_eq!(4, unsafe { mem::align_of_val_raw(&5i32) });
568/// ```
569#[inline]
570#[must_use]
571#[unstable(feature = "layout_for_ptr", issue = "69835")]
572#[cfg(not(feature = "ferrocene_subset"))]
573pub const unsafe fn align_of_val_raw<T: ?Sized>(val: *const T) -> usize {
574 // SAFETY: the caller must provide a valid raw pointer
575 unsafe { intrinsics::align_of_val(val) }
576}
577
578/// Returns `true` if dropping values of type `T` matters.
579///
580/// This is purely an optimization hint, and may be implemented conservatively:
581/// it may return `true` for types that don't actually need to be dropped.
582/// As such always returning `true` would be a valid implementation of
583/// this function. However if this function actually returns `false`, then you
584/// can be certain dropping `T` has no side effect.
585///
586/// Low level implementations of things like collections, which need to manually
587/// drop their data, should use this function to avoid unnecessarily
588/// trying to drop all their contents when they are destroyed. This might not
589/// make a difference in release builds (where a loop that has no side-effects
590/// is easily detected and eliminated), but is often a big win for debug builds.
591///
592/// Note that [`drop_in_place`] already performs this check, so if your workload
593/// can be reduced to some small number of [`drop_in_place`] calls, using this is
594/// unnecessary. In particular note that you can [`drop_in_place`] a slice, and that
595/// will do a single needs_drop check for all the values.
596///
597/// Types like Vec therefore just `drop_in_place(&mut self[..])` without using
598/// `needs_drop` explicitly. Types like [`HashMap`], on the other hand, have to drop
599/// values one at a time and should use this API.
600///
601/// [`drop_in_place`]: crate::ptr::drop_in_place
602/// [`HashMap`]: ../../std/collections/struct.HashMap.html
603///
604/// # Examples
605///
606/// Here's an example of how a collection might make use of `needs_drop`:
607///
608/// ```
609/// use std::{mem, ptr};
610///
611/// pub struct MyCollection<T> {
612/// # data: [T; 1],
613/// /* ... */
614/// }
615/// # impl<T> MyCollection<T> {
616/// # fn iter_mut(&mut self) -> &mut [T] { &mut self.data }
617/// # fn free_buffer(&mut self) {}
618/// # }
619///
620/// impl<T> Drop for MyCollection<T> {
621/// fn drop(&mut self) {
622/// unsafe {
623/// // drop the data
624/// if mem::needs_drop::<T>() {
625/// for x in self.iter_mut() {
626/// ptr::drop_in_place(x);
627/// }
628/// }
629/// self.free_buffer();
630/// }
631/// }
632/// }
633/// ```
634#[inline]
635#[must_use]
636#[stable(feature = "needs_drop", since = "1.21.0")]
637#[rustc_const_stable(feature = "const_mem_needs_drop", since = "1.36.0")]
638#[rustc_diagnostic_item = "needs_drop"]
639pub const fn needs_drop<T: ?Sized>() -> bool {
640 const { intrinsics::needs_drop::<T>() }
641}
642
643/// Returns the value of type `T` represented by the all-zero byte-pattern.
644///
645/// This means that, for example, the padding byte in `(u8, u16)` is not
646/// necessarily zeroed.
647///
648/// There is no guarantee that an all-zero byte-pattern represents a valid value
649/// of some type `T`. For example, the all-zero byte-pattern is not a valid value
650/// for reference types (`&T`, `&mut T`) and function pointers. Using `zeroed`
651/// on such types causes immediate [undefined behavior][ub] because [the Rust
652/// compiler assumes][inv] that there always is a valid value in a variable it
653/// considers initialized.
654///
655/// This has the same effect as [`MaybeUninit::zeroed().assume_init()`][zeroed].
656/// It is useful for FFI sometimes, but should generally be avoided.
657///
658/// [zeroed]: MaybeUninit::zeroed
659/// [ub]: ../../reference/behavior-considered-undefined.html
660/// [inv]: MaybeUninit#initialization-invariant
661///
662/// # Examples
663///
664/// Correct usage of this function: initializing an integer with zero.
665///
666/// ```
667/// use std::mem;
668///
669/// let x: i32 = unsafe { mem::zeroed() };
670/// assert_eq!(0, x);
671/// ```
672///
673/// *Incorrect* usage of this function: initializing a reference with zero.
674///
675/// ```rust,no_run
676/// # #![allow(invalid_value)]
677/// use std::mem;
678///
679/// let _x: &i32 = unsafe { mem::zeroed() }; // Undefined behavior!
680/// let _y: fn() = unsafe { mem::zeroed() }; // And again!
681/// ```
682#[inline(always)]
683#[must_use]
684#[stable(feature = "rust1", since = "1.0.0")]
685#[rustc_diagnostic_item = "mem_zeroed"]
686#[track_caller]
687#[rustc_const_stable(feature = "const_mem_zeroed", since = "1.75.0")]
688pub const unsafe fn zeroed<T>() -> T {
689 // SAFETY: the caller must guarantee that an all-zero value is valid for `T`.
690 unsafe {
691 intrinsics::assert_zero_valid::<T>();
692 MaybeUninit::zeroed().assume_init()
693 }
694}
695
696/// Bypasses Rust's normal memory-initialization checks by pretending to
697/// produce a value of type `T`, while doing nothing at all.
698///
699/// **This function is deprecated.** Use [`MaybeUninit<T>`] instead.
700/// It also might be slower than using `MaybeUninit<T>` due to mitigations that were put in place to
701/// limit the potential harm caused by incorrect use of this function in legacy code.
702///
703/// The reason for deprecation is that the function basically cannot be used
704/// correctly: it has the same effect as [`MaybeUninit::uninit().assume_init()`][uninit].
705/// As the [`assume_init` documentation][assume_init] explains,
706/// [the Rust compiler assumes][inv] that values are properly initialized.
707///
708/// Truly uninitialized memory like what gets returned here
709/// is special in that the compiler knows that it does not have a fixed value.
710/// This makes it undefined behavior to have uninitialized data in a variable even
711/// if that variable has an integer type.
712///
713/// Therefore, it is immediate undefined behavior to call this function on nearly all types,
714/// including integer types and arrays of integer types, and even if the result is unused.
715///
716/// [uninit]: MaybeUninit::uninit
717/// [assume_init]: MaybeUninit::assume_init
718/// [inv]: MaybeUninit#initialization-invariant
719#[inline(always)]
720#[must_use]
721#[deprecated(since = "1.39.0", note = "use `mem::MaybeUninit` instead")]
722#[stable(feature = "rust1", since = "1.0.0")]
723#[rustc_diagnostic_item = "mem_uninitialized"]
724#[track_caller]
725#[cfg(not(feature = "ferrocene_subset"))]
726pub unsafe fn uninitialized<T>() -> T {
727 // SAFETY: the caller must guarantee that an uninitialized value is valid for `T`.
728 unsafe {
729 intrinsics::assert_mem_uninitialized_valid::<T>();
730 let mut val = MaybeUninit::<T>::uninit();
731
732 // Fill memory with 0x01, as an imperfect mitigation for old code that uses this function on
733 // bool, nonnull, and noundef types. But don't do this if we actively want to detect UB.
734 if !cfg!(any(miri, sanitize = "memory")) {
735 val.as_mut_ptr().write_bytes(0x01, 1);
736 }
737
738 val.assume_init()
739 }
740}
741
742/// Swaps the values at two mutable locations, without deinitializing either one.
743///
744/// * If you want to swap with a default or dummy value, see [`take`].
745/// * If you want to swap with a passed value, returning the old value, see [`replace`].
746///
747/// # Examples
748///
749/// ```
750/// use std::mem;
751///
752/// let mut x = 5;
753/// let mut y = 42;
754///
755/// mem::swap(&mut x, &mut y);
756///
757/// assert_eq!(42, x);
758/// assert_eq!(5, y);
759/// ```
760#[inline]
761#[stable(feature = "rust1", since = "1.0.0")]
762#[rustc_const_stable(feature = "const_swap", since = "1.85.0")]
763#[rustc_diagnostic_item = "mem_swap"]
764pub const fn swap<T>(x: &mut T, y: &mut T) {
765 // SAFETY: `&mut` guarantees these are typed readable and writable
766 // as well as non-overlapping.
767 unsafe { intrinsics::typed_swap_nonoverlapping(x, y) }
768}
769
770/// Replaces `dest` with the default value of `T`, returning the previous `dest` value.
771///
772/// * If you want to replace the values of two variables, see [`swap`].
773/// * If you want to replace with a passed value instead of the default value, see [`replace`].
774///
775/// # Examples
776///
777/// A simple example:
778///
779/// ```
780/// use std::mem;
781///
782/// let mut v: Vec<i32> = vec![1, 2];
783///
784/// let old_v = mem::take(&mut v);
785/// assert_eq!(vec![1, 2], old_v);
786/// assert!(v.is_empty());
787/// ```
788///
789/// `take` allows taking ownership of a struct field by replacing it with an "empty" value.
790/// Without `take` you can run into issues like these:
791///
792/// ```compile_fail,E0507
793/// struct Buffer<T> { buf: Vec<T> }
794///
795/// impl<T> Buffer<T> {
796/// fn get_and_reset(&mut self) -> Vec<T> {
797/// // error: cannot move out of dereference of `&mut`-pointer
798/// let buf = self.buf;
799/// self.buf = Vec::new();
800/// buf
801/// }
802/// }
803/// ```
804///
805/// Note that `T` does not necessarily implement [`Clone`], so it can't even clone and reset
806/// `self.buf`. But `take` can be used to disassociate the original value of `self.buf` from
807/// `self`, allowing it to be returned:
808///
809/// ```
810/// use std::mem;
811///
812/// # struct Buffer<T> { buf: Vec<T> }
813/// impl<T> Buffer<T> {
814/// fn get_and_reset(&mut self) -> Vec<T> {
815/// mem::take(&mut self.buf)
816/// }
817/// }
818///
819/// let mut buffer = Buffer { buf: vec![0, 1] };
820/// assert_eq!(buffer.buf.len(), 2);
821///
822/// assert_eq!(buffer.get_and_reset(), vec![0, 1]);
823/// assert_eq!(buffer.buf.len(), 0);
824/// ```
825#[inline]
826#[stable(feature = "mem_take", since = "1.40.0")]
827#[rustc_const_unstable(feature = "const_default", issue = "143894")]
828pub const fn take<T: [const] Default>(dest: &mut T) -> T {
829 replace(dest, T::default())
830}
831
832/// Moves `src` into the referenced `dest`, returning the previous `dest` value.
833///
834/// Neither value is dropped.
835///
836/// * If you want to replace the values of two variables, see [`swap`].
837/// * If you want to replace with a default value, see [`take`].
838///
839/// # Examples
840///
841/// A simple example:
842///
843/// ```
844/// use std::mem;
845///
846/// let mut v: Vec<i32> = vec![1, 2];
847///
848/// let old_v = mem::replace(&mut v, vec![3, 4, 5]);
849/// assert_eq!(vec![1, 2], old_v);
850/// assert_eq!(vec![3, 4, 5], v);
851/// ```
852///
853/// `replace` allows consumption of a struct field by replacing it with another value.
854/// Without `replace` you can run into issues like these:
855///
856/// ```compile_fail,E0507
857/// struct Buffer<T> { buf: Vec<T> }
858///
859/// impl<T> Buffer<T> {
860/// fn replace_index(&mut self, i: usize, v: T) -> T {
861/// // error: cannot move out of dereference of `&mut`-pointer
862/// let t = self.buf[i];
863/// self.buf[i] = v;
864/// t
865/// }
866/// }
867/// ```
868///
869/// Note that `T` does not necessarily implement [`Clone`], so we can't even clone `self.buf[i]` to
870/// avoid the move. But `replace` can be used to disassociate the original value at that index from
871/// `self`, allowing it to be returned:
872///
873/// ```
874/// # #![allow(dead_code)]
875/// use std::mem;
876///
877/// # struct Buffer<T> { buf: Vec<T> }
878/// impl<T> Buffer<T> {
879/// fn replace_index(&mut self, i: usize, v: T) -> T {
880/// mem::replace(&mut self.buf[i], v)
881/// }
882/// }
883///
884/// let mut buffer = Buffer { buf: vec![0, 1] };
885/// assert_eq!(buffer.buf[0], 0);
886///
887/// assert_eq!(buffer.replace_index(0, 2), 0);
888/// assert_eq!(buffer.buf[0], 2);
889/// ```
890#[inline]
891#[stable(feature = "rust1", since = "1.0.0")]
892#[must_use = "if you don't need the old value, you can just assign the new value directly"]
893#[rustc_const_stable(feature = "const_replace", since = "1.83.0")]
894#[rustc_diagnostic_item = "mem_replace"]
895pub const fn replace<T>(dest: &mut T, src: T) -> T {
896 // It may be tempting to use `swap` to avoid `unsafe` here. Don't!
897 // The compiler optimizes the implementation below to two `memcpy`s
898 // while `swap` would require at least three. See PR#83022 for details.
899
900 // SAFETY: We read from `dest` but directly write `src` into it afterwards,
901 // such that the old value is not duplicated. Nothing is dropped and
902 // nothing here can panic.
903 unsafe {
904 // Ideally we wouldn't use the intrinsics here, but going through the
905 // `ptr` methods introduces two unnecessary UbChecks, so until we can
906 // remove those for pointers that come from references, this uses the
907 // intrinsics instead so this stays very cheap in MIR (and debug).
908
909 let result = crate::intrinsics::read_via_copy(dest);
910 crate::intrinsics::write_via_move(dest, src);
911 result
912 }
913}
914
915/// Disposes of a value.
916///
917/// This effectively does nothing for types which implement `Copy`, e.g.
918/// integers. Such values are copied and _then_ moved into the function, so the
919/// value persists after this function call.
920///
921/// This function is not magic; it is literally defined as
922///
923/// ```
924/// pub fn drop<T>(_x: T) {}
925/// ```
926///
927/// Because `_x` is moved into the function, it is automatically [dropped][drop] before
928/// the function returns.
929///
930/// [drop]: Drop
931///
932/// # Examples
933///
934/// Basic usage:
935///
936/// ```
937/// let v = vec![1, 2, 3];
938///
939/// drop(v); // explicitly drop the vector
940/// ```
941///
942/// Since [`RefCell`] enforces the borrow rules at runtime, `drop` can
943/// release a [`RefCell`] borrow:
944///
945/// ```
946/// use std::cell::RefCell;
947///
948/// let x = RefCell::new(1);
949///
950/// let mut mutable_borrow = x.borrow_mut();
951/// *mutable_borrow = 1;
952///
953/// drop(mutable_borrow); // relinquish the mutable borrow on this slot
954///
955/// let borrow = x.borrow();
956/// println!("{}", *borrow);
957/// ```
958///
959/// Integers and other types implementing [`Copy`] are unaffected by `drop`.
960///
961/// ```
962/// # #![allow(dropping_copy_types)]
963/// #[derive(Copy, Clone)]
964/// struct Foo(u8);
965///
966/// let x = 1;
967/// let y = Foo(2);
968/// drop(x); // a copy of `x` is moved and dropped
969/// drop(y); // a copy of `y` is moved and dropped
970///
971/// println!("x: {}, y: {}", x, y.0); // still available
972/// ```
973///
974/// [`RefCell`]: crate::cell::RefCell
975#[inline]
976#[stable(feature = "rust1", since = "1.0.0")]
977#[rustc_const_unstable(feature = "const_destruct", issue = "133214")]
978#[rustc_diagnostic_item = "mem_drop"]
979pub const fn drop<T>(_x: T)
980where
981 T: [const] Destruct,
982{
983}
984
985/// Bitwise-copies a value.
986///
987/// This function is not magic; it is literally defined as
988/// ```
989/// pub const fn copy<T: Copy>(x: &T) -> T { *x }
990/// ```
991///
992/// It is useful when you want to pass a function pointer to a combinator, rather than defining a new closure.
993///
994/// Example:
995/// ```
996/// #![feature(mem_copy_fn)]
997/// use core::mem::copy;
998/// let result_from_ffi_function: Result<(), &i32> = Err(&1);
999/// let result_copied: Result<(), i32> = result_from_ffi_function.map_err(copy);
1000/// ```
1001#[inline]
1002#[unstable(feature = "mem_copy_fn", issue = "98262")]
1003#[cfg(not(feature = "ferrocene_subset"))]
1004pub const fn copy<T: Copy>(x: &T) -> T {
1005 *x
1006}
1007
1008/// Interprets `src` as having type `&Dst`, and then reads `src` without moving
1009/// the contained value.
1010///
1011/// This function will unsafely assume the pointer `src` is valid for [`size_of::<Dst>`][size_of]
1012/// bytes by transmuting `&Src` to `&Dst` and then reading the `&Dst` (except that this is done
1013/// in a way that is correct even when `&Dst` has stricter alignment requirements than `&Src`).
1014/// It will also unsafely create a copy of the contained value instead of moving out of `src`.
1015///
1016/// It is not a compile-time error if `Src` and `Dst` have different sizes, but it
1017/// is highly encouraged to only invoke this function where `Src` and `Dst` have the
1018/// same size. This function triggers [undefined behavior][ub] if `Dst` is larger than
1019/// `Src`.
1020///
1021/// [ub]: ../../reference/behavior-considered-undefined.html
1022///
1023/// # Examples
1024///
1025/// ```
1026/// use std::mem;
1027///
1028/// #[repr(packed)]
1029/// struct Foo {
1030/// bar: u8,
1031/// }
1032///
1033/// let foo_array = [10u8];
1034///
1035/// unsafe {
1036/// // Copy the data from 'foo_array' and treat it as a 'Foo'
1037/// let mut foo_struct: Foo = mem::transmute_copy(&foo_array);
1038/// assert_eq!(foo_struct.bar, 10);
1039///
1040/// // Modify the copied data
1041/// foo_struct.bar = 20;
1042/// assert_eq!(foo_struct.bar, 20);
1043/// }
1044///
1045/// // The contents of 'foo_array' should not have changed
1046/// assert_eq!(foo_array, [10]);
1047/// ```
1048#[inline]
1049#[must_use]
1050#[track_caller]
1051#[stable(feature = "rust1", since = "1.0.0")]
1052#[rustc_const_stable(feature = "const_transmute_copy", since = "1.74.0")]
1053pub const unsafe fn transmute_copy<Src, Dst>(src: &Src) -> Dst {
1054 assert!(
1055 size_of::<Src>() >= size_of::<Dst>(),
1056 "cannot transmute_copy if Dst is larger than Src"
1057 );
1058
1059 // If Dst has a higher alignment requirement, src might not be suitably aligned.
1060 if align_of::<Dst>() > align_of::<Src>() {
1061 // SAFETY: `src` is a reference which is guaranteed to be valid for reads.
1062 // The caller must guarantee that the actual transmutation is safe.
1063 unsafe { ptr::read_unaligned(src as *const Src as *const Dst) }
1064 } else {
1065 // SAFETY: `src` is a reference which is guaranteed to be valid for reads.
1066 // We just checked that `src as *const Dst` was properly aligned.
1067 // The caller must guarantee that the actual transmutation is safe.
1068 unsafe { ptr::read(src as *const Src as *const Dst) }
1069 }
1070}
1071
1072/// Opaque type representing the discriminant of an enum.
1073///
1074/// See the [`discriminant`] function in this module for more information.
1075#[stable(feature = "discriminant_value", since = "1.21.0")]
1076pub struct Discriminant<T>(<T as DiscriminantKind>::Discriminant);
1077
1078// N.B. These trait implementations cannot be derived because we don't want any bounds on T.
1079
1080#[stable(feature = "discriminant_value", since = "1.21.0")]
1081#[cfg(not(feature = "ferrocene_subset"))]
1082impl<T> Copy for Discriminant<T> {}
1083
1084#[stable(feature = "discriminant_value", since = "1.21.0")]
1085#[cfg(not(feature = "ferrocene_subset"))]
1086impl<T> clone::Clone for Discriminant<T> {
1087 fn clone(&self) -> Self {
1088 *self
1089 }
1090}
1091
1092#[cfg(not(feature = "ferrocene_subset"))]
1093#[doc(hidden)]
1094#[unstable(feature = "trivial_clone", issue = "none")]
1095unsafe impl<T> TrivialClone for Discriminant<T> {}
1096
1097#[stable(feature = "discriminant_value", since = "1.21.0")]
1098impl<T> cmp::PartialEq for Discriminant<T> {
1099 fn eq(&self, rhs: &Self) -> bool {
1100 self.0 == rhs.0
1101 }
1102}
1103
1104#[stable(feature = "discriminant_value", since = "1.21.0")]
1105#[cfg(not(feature = "ferrocene_subset"))]
1106impl<T> cmp::Eq for Discriminant<T> {}
1107
1108#[stable(feature = "discriminant_value", since = "1.21.0")]
1109#[cfg(not(feature = "ferrocene_subset"))]
1110impl<T> hash::Hash for Discriminant<T> {
1111 fn hash<H: hash::Hasher>(&self, state: &mut H) {
1112 self.0.hash(state);
1113 }
1114}
1115
1116#[stable(feature = "discriminant_value", since = "1.21.0")]
1117#[cfg(not(feature = "ferrocene_subset"))]
1118impl<T> fmt::Debug for Discriminant<T> {
1119 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
1120 fmt.debug_tuple("Discriminant").field(&self.0).finish()
1121 }
1122}
1123
1124/// Returns a value uniquely identifying the enum variant in `v`.
1125///
1126/// If `T` is not an enum, calling this function will not result in undefined behavior, but the
1127/// return value is unspecified.
1128///
1129/// # Stability
1130///
1131/// The discriminant of an enum variant may change if the enum definition changes. A discriminant
1132/// of some variant will not change between compilations with the same compiler. See the [Reference]
1133/// for more information.
1134///
1135/// [Reference]: ../../reference/items/enumerations.html#custom-discriminant-values-for-fieldless-enumerations
1136///
1137/// The value of a [`Discriminant<T>`] is independent of any *free lifetimes* in `T`. As such,
1138/// reading or writing a `Discriminant<Foo<'a>>` as a `Discriminant<Foo<'b>>` (whether via
1139/// [`transmute`] or otherwise) is always sound. Note that this is **not** true for other kinds
1140/// of generic parameters and for higher-ranked lifetimes; `Discriminant<Foo<A>>` and
1141/// `Discriminant<Foo<B>>` as well as `Discriminant<Bar<dyn for<'a> Trait<'a>>>` and
1142/// `Discriminant<Bar<dyn Trait<'static>>>` may be incompatible.
1143///
1144/// # Examples
1145///
1146/// This can be used to compare enums that carry data, while disregarding
1147/// the actual data:
1148///
1149/// ```
1150/// use std::mem;
1151///
1152/// enum Foo { A(&'static str), B(i32), C(i32) }
1153///
1154/// assert_eq!(mem::discriminant(&Foo::A("bar")), mem::discriminant(&Foo::A("baz")));
1155/// assert_eq!(mem::discriminant(&Foo::B(1)), mem::discriminant(&Foo::B(2)));
1156/// assert_ne!(mem::discriminant(&Foo::B(3)), mem::discriminant(&Foo::C(3)));
1157/// ```
1158///
1159/// ## Accessing the numeric value of the discriminant
1160///
1161/// Note that it is *undefined behavior* to [`transmute`] from [`Discriminant`] to a primitive!
1162///
1163/// If an enum has only unit variants, then the numeric value of the discriminant can be accessed
1164/// with an [`as`] cast:
1165///
1166/// ```
1167/// enum Enum {
1168/// Foo,
1169/// Bar,
1170/// Baz,
1171/// }
1172///
1173/// assert_eq!(0, Enum::Foo as isize);
1174/// assert_eq!(1, Enum::Bar as isize);
1175/// assert_eq!(2, Enum::Baz as isize);
1176/// ```
1177///
1178/// If an enum has opted-in to having a [primitive representation] for its discriminant,
1179/// then it's possible to use pointers to read the memory location storing the discriminant.
1180/// That **cannot** be done for enums using the [default representation], however, as it's
1181/// undefined what layout the discriminant has and where it's stored — it might not even be
1182/// stored at all!
1183///
1184/// [`as`]: ../../std/keyword.as.html
1185/// [primitive representation]: ../../reference/type-layout.html#primitive-representations
1186/// [default representation]: ../../reference/type-layout.html#the-default-representation
1187/// ```
1188/// #[repr(u8)]
1189/// enum Enum {
1190/// Unit,
1191/// Tuple(bool),
1192/// Struct { a: bool },
1193/// }
1194///
1195/// impl Enum {
1196/// fn discriminant(&self) -> u8 {
1197/// // SAFETY: Because `Self` is marked `repr(u8)`, its layout is a `repr(C)` `union`
1198/// // between `repr(C)` structs, each of which has the `u8` discriminant as its first
1199/// // field, so we can read the discriminant without offsetting the pointer.
1200/// unsafe { *<*const _>::from(self).cast::<u8>() }
1201/// }
1202/// }
1203///
1204/// let unit_like = Enum::Unit;
1205/// let tuple_like = Enum::Tuple(true);
1206/// let struct_like = Enum::Struct { a: false };
1207/// assert_eq!(0, unit_like.discriminant());
1208/// assert_eq!(1, tuple_like.discriminant());
1209/// assert_eq!(2, struct_like.discriminant());
1210///
1211/// // ⚠️ This is undefined behavior. Don't do this. ⚠️
1212/// // assert_eq!(0, unsafe { std::mem::transmute::<_, u8>(std::mem::discriminant(&unit_like)) });
1213/// ```
1214#[stable(feature = "discriminant_value", since = "1.21.0")]
1215#[rustc_const_stable(feature = "const_discriminant", since = "1.75.0")]
1216#[rustc_diagnostic_item = "mem_discriminant"]
1217#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
1218pub const fn discriminant<T>(v: &T) -> Discriminant<T> {
1219 Discriminant(intrinsics::discriminant_value(v))
1220}
1221
1222/// Returns the number of variants in the enum type `T`.
1223///
1224/// If `T` is not an enum, calling this function will not result in undefined behavior, but the
1225/// return value is unspecified. Equally, if `T` is an enum with more variants than `usize::MAX`
1226/// the return value is unspecified. Uninhabited variants will be counted.
1227///
1228/// Note that an enum may be expanded with additional variants in the future
1229/// as a non-breaking change, for example if it is marked `#[non_exhaustive]`,
1230/// which will change the result of this function.
1231///
1232/// # Examples
1233///
1234/// ```
1235/// # #![feature(never_type)]
1236/// # #![feature(variant_count)]
1237///
1238/// use std::mem;
1239///
1240/// enum Void {}
1241/// enum Foo { A(&'static str), B(i32), C(i32) }
1242///
1243/// assert_eq!(mem::variant_count::<Void>(), 0);
1244/// assert_eq!(mem::variant_count::<Foo>(), 3);
1245///
1246/// assert_eq!(mem::variant_count::<Option<!>>(), 2);
1247/// assert_eq!(mem::variant_count::<Result<!, !>>(), 2);
1248/// ```
1249#[inline(always)]
1250#[must_use]
1251#[unstable(feature = "variant_count", issue = "73662")]
1252#[rustc_const_unstable(feature = "variant_count", issue = "73662")]
1253#[rustc_diagnostic_item = "mem_variant_count"]
1254#[cfg(not(feature = "ferrocene_subset"))]
1255pub const fn variant_count<T>() -> usize {
1256 const { intrinsics::variant_count::<T>() }
1257}
1258
1259/// Provides associated constants for various useful properties of types,
1260/// to give them a canonical form in our code and make them easier to read.
1261///
1262/// This is here only to simplify all the ZST checks we need in the library.
1263/// It's not on a stabilization track right now.
1264#[doc(hidden)]
1265#[unstable(feature = "sized_type_properties", issue = "none")]
1266pub trait SizedTypeProperties: Sized {
1267 #[doc(hidden)]
1268 #[unstable(feature = "sized_type_properties", issue = "none")]
1269 #[lang = "mem_size_const"]
1270 const SIZE: usize = intrinsics::size_of::<Self>();
1271
1272 #[doc(hidden)]
1273 #[unstable(feature = "sized_type_properties", issue = "none")]
1274 #[lang = "mem_align_const"]
1275 const ALIGN: usize = intrinsics::align_of::<Self>();
1276
1277 /// `true` if this type requires no storage.
1278 /// `false` if its [size](size_of) is greater than zero.
1279 ///
1280 /// # Examples
1281 ///
1282 /// ```
1283 /// #![feature(sized_type_properties)]
1284 /// use core::mem::SizedTypeProperties;
1285 ///
1286 /// fn do_something_with<T>() {
1287 /// if T::IS_ZST {
1288 /// // ... special approach ...
1289 /// } else {
1290 /// // ... the normal thing ...
1291 /// }
1292 /// }
1293 ///
1294 /// struct MyUnit;
1295 /// assert!(MyUnit::IS_ZST);
1296 ///
1297 /// // For negative checks, consider using UFCS to emphasize the negation
1298 /// assert!(!<i32>::IS_ZST);
1299 /// // As it can sometimes hide in the type otherwise
1300 /// assert!(!String::IS_ZST);
1301 /// ```
1302 #[doc(hidden)]
1303 #[unstable(feature = "sized_type_properties", issue = "none")]
1304 const IS_ZST: bool = Self::SIZE == 0;
1305
1306 #[doc(hidden)]
1307 #[unstable(feature = "sized_type_properties", issue = "none")]
1308 const LAYOUT: Layout = {
1309 // SAFETY: if the type is instantiated, rustc already ensures that its
1310 // layout is valid. Use the unchecked constructor to avoid inserting a
1311 // panicking codepath that needs to be optimized out.
1312 unsafe { Layout::from_size_align_unchecked(Self::SIZE, Self::ALIGN) }
1313 };
1314
1315 /// The largest safe length for a `[Self]`.
1316 ///
1317 /// Anything larger than this would make `size_of_val` overflow `isize::MAX`,
1318 /// which is never allowed for a single object.
1319 #[doc(hidden)]
1320 #[unstable(feature = "sized_type_properties", issue = "none")]
1321 const MAX_SLICE_LEN: usize = match Self::SIZE {
1322 0 => usize::MAX,
1323 n => (isize::MAX as usize) / n,
1324 };
1325}
1326#[doc(hidden)]
1327#[unstable(feature = "sized_type_properties", issue = "none")]
1328impl<T> SizedTypeProperties for T {}
1329
1330/// Expands to the offset in bytes of a field from the beginning of the given type.
1331///
1332/// The type may be a `struct`, `enum`, `union`, or tuple.
1333///
1334/// The field may be a nested field (`field1.field2`), but not an array index.
1335/// The field must be visible to the call site.
1336///
1337/// The offset is returned as a [`usize`].
1338///
1339/// # Offsets of, and in, dynamically sized types
1340///
1341/// The field’s type must be [`Sized`], but it may be located in a [dynamically sized] container.
1342/// If the field type is dynamically sized, then you cannot use `offset_of!` (since the field's
1343/// alignment, and therefore its offset, may also be dynamic) and must take the offset from an
1344/// actual pointer to the container instead.
1345///
1346/// ```
1347/// # use core::mem;
1348/// # use core::fmt::Debug;
1349/// #[repr(C)]
1350/// pub struct Struct<T: ?Sized> {
1351/// a: u8,
1352/// b: T,
1353/// }
1354///
1355/// #[derive(Debug)]
1356/// #[repr(C, align(4))]
1357/// struct Align4(u32);
1358///
1359/// assert_eq!(mem::offset_of!(Struct<dyn Debug>, a), 0); // OK — Sized field
1360/// assert_eq!(mem::offset_of!(Struct<Align4>, b), 4); // OK — not DST
1361///
1362/// // assert_eq!(mem::offset_of!(Struct<dyn Debug>, b), 1);
1363/// // ^^^ error[E0277]: ... cannot be known at compilation time
1364///
1365/// // To obtain the offset of a !Sized field, examine a concrete value
1366/// // instead of using offset_of!.
1367/// let value: Struct<Align4> = Struct { a: 1, b: Align4(2) };
1368/// let ref_unsized: &Struct<dyn Debug> = &value;
1369/// let offset_of_b = unsafe {
1370/// (&raw const ref_unsized.b).byte_offset_from_unsigned(ref_unsized)
1371/// };
1372/// assert_eq!(offset_of_b, 4);
1373/// ```
1374///
1375/// If you need to obtain the offset of a field of a `!Sized` type, then, since the offset may
1376/// depend on the particular value being stored (in particular, `dyn Trait` values have a
1377/// dynamically-determined alignment), you must retrieve the offset from a specific reference
1378/// or pointer, and so you cannot use `offset_of!` to work without one.
1379///
1380/// # Layout is subject to change
1381///
1382/// Note that type layout is, in general, [subject to change and
1383/// platform-specific](https://doc.rust-lang.org/reference/type-layout.html). If
1384/// layout stability is required, consider using an [explicit `repr` attribute].
1385///
1386/// Rust guarantees that the offset of a given field within a given type will not
1387/// change over the lifetime of the program. However, two different compilations of
1388/// the same program may result in different layouts. Also, even within a single
1389/// program execution, no guarantees are made about types which are *similar* but
1390/// not *identical*, e.g.:
1391///
1392/// ```
1393/// struct Wrapper<T, U>(T, U);
1394///
1395/// type A = Wrapper<u8, u8>;
1396/// type B = Wrapper<u8, i8>;
1397///
1398/// // Not necessarily identical even though `u8` and `i8` have the same layout!
1399/// // assert_eq!(mem::offset_of!(A, 1), mem::offset_of!(B, 1));
1400///
1401/// #[repr(transparent)]
1402/// struct U8(u8);
1403///
1404/// type C = Wrapper<u8, U8>;
1405///
1406/// // Not necessarily identical even though `u8` and `U8` have the same layout!
1407/// // assert_eq!(mem::offset_of!(A, 1), mem::offset_of!(C, 1));
1408///
1409/// struct Empty<T>(core::marker::PhantomData<T>);
1410///
1411/// // Not necessarily identical even though `PhantomData` always has the same layout!
1412/// // assert_eq!(mem::offset_of!(Empty<u8>, 0), mem::offset_of!(Empty<i8>, 0));
1413/// ```
1414///
1415/// [explicit `repr` attribute]: https://doc.rust-lang.org/reference/type-layout.html#representations
1416///
1417/// # Unstable features
1418///
1419/// The following unstable features expand the functionality of `offset_of!`:
1420///
1421/// * [`offset_of_enum`] — allows `enum` variants to be traversed as if they were fields.
1422/// * [`offset_of_slice`] — allows getting the offset of a field of type `[T]`.
1423///
1424/// # Examples
1425///
1426/// ```
1427/// use std::mem;
1428/// #[repr(C)]
1429/// struct FieldStruct {
1430/// first: u8,
1431/// second: u16,
1432/// third: u8
1433/// }
1434///
1435/// assert_eq!(mem::offset_of!(FieldStruct, first), 0);
1436/// assert_eq!(mem::offset_of!(FieldStruct, second), 2);
1437/// assert_eq!(mem::offset_of!(FieldStruct, third), 4);
1438///
1439/// #[repr(C)]
1440/// struct NestedA {
1441/// b: NestedB
1442/// }
1443///
1444/// #[repr(C)]
1445/// struct NestedB(u8);
1446///
1447/// assert_eq!(mem::offset_of!(NestedA, b.0), 0);
1448/// ```
1449///
1450/// [dynamically sized]: https://doc.rust-lang.org/reference/dynamically-sized-types.html
1451/// [`offset_of_enum`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-enum.html
1452/// [`offset_of_slice`]: https://doc.rust-lang.org/nightly/unstable-book/language-features/offset-of-slice.html
1453#[stable(feature = "offset_of", since = "1.77.0")]
1454#[allow_internal_unstable(builtin_syntax, core_intrinsics)]
1455pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
1456 // The `{}` is for better error messages
1457 const {builtin # offset_of($Container, $($fields)+)}
1458}
1459
1460/// Create a fresh instance of the inhabited ZST type `T`.
1461///
1462/// Prefer this to [`zeroed`] or [`uninitialized`] or [`transmute_copy`]
1463/// in places where you know that `T` is zero-sized, but don't have a bound
1464/// (such as [`Default`]) that would allow you to instantiate it using safe code.
1465///
1466/// If you're not sure whether `T` is an inhabited ZST, then you should be
1467/// using [`MaybeUninit`], not this function.
1468///
1469/// # Panics
1470///
1471/// If `size_of::<T>() != 0`.
1472///
1473/// # Safety
1474///
1475/// - `T` must be *[inhabited]*, i.e. possible to construct. This means that types
1476/// like zero-variant enums and [`!`] are unsound to conjure.
1477/// - You must use the value only in ways which do not violate any *safety*
1478/// invariants of the type.
1479///
1480/// While it's easy to create a *valid* instance of an inhabited ZST, since having
1481/// no bits in its representation means there's only one possible value, that
1482/// doesn't mean that it's always *sound* to do so.
1483///
1484/// For example, a library could design zero-sized tokens that are `!Default + !Clone`, limiting
1485/// their creation to functions that initialize some state or establish a scope. Conjuring such a
1486/// token could break invariants and lead to unsoundness.
1487///
1488/// # Examples
1489///
1490/// ```
1491/// #![feature(mem_conjure_zst)]
1492/// use std::mem::conjure_zst;
1493///
1494/// assert_eq!(unsafe { conjure_zst::<()>() }, ());
1495/// assert_eq!(unsafe { conjure_zst::<[i32; 0]>() }, []);
1496/// ```
1497///
1498/// [inhabited]: https://doc.rust-lang.org/reference/glossary.html#inhabited
1499#[unstable(feature = "mem_conjure_zst", issue = "95383")]
1500pub const unsafe fn conjure_zst<T>() -> T {
1501 const_assert!(
1502 size_of::<T>() == 0,
1503 "mem::conjure_zst invoked on a nonzero-sized type",
1504 "mem::conjure_zst invoked on type {t}, which is not zero-sized",
1505 t: &str = stringify!(T)
1506 );
1507
1508 // SAFETY: because the caller must guarantee that it's inhabited and zero-sized,
1509 // there's nothing in the representation that needs to be set.
1510 // `assume_init` calls `assert_inhabited`, so we don't need to here.
1511 unsafe {
1512 #[allow(clippy::uninit_assumed_init)]
1513 MaybeUninit::uninit().assume_init()
1514 }
1515}