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