Skip to main content

core/intrinsics/
mod.rs

1//! Compiler intrinsics.
2//!
3//! The functions in this module are implementation details of `core` and should
4//! not be used outside of the standard library. We generally provide access to
5//! intrinsics via stable wrapper functions. Use these instead.
6//!
7//! These are the imports making intrinsics available to Rust code. The actual implementations live in the compiler.
8//! Some of these intrinsics are lowered to MIR in <https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_mir_transform/src/lower_intrinsics.rs>.
9//! The remaining intrinsics are implemented for the LLVM backend in <https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_codegen_ssa/src/mir/intrinsic.rs>
10//! and <https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_codegen_llvm/src/intrinsic.rs>,
11//! and for const evaluation in <https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_const_eval/src/interpret/intrinsics.rs>.
12//!
13//! # Const intrinsics
14//!
15//! In order to make an intrinsic unstable usable at compile-time, copy the implementation from
16//! <https://github.com/rust-lang/miri/blob/master/src/intrinsics> to
17//! <https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_const_eval/src/interpret/intrinsics.rs>
18//! and make the intrinsic declaration below a `const fn`. This should be done in coordination with
19//! wg-const-eval.
20//!
21//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
22//! `#[rustc_intrinsic_const_stable_indirect]` needs to be added to the intrinsic. Such a change requires
23//! T-lang approval, because it may bake a feature into the language that cannot be replicated in
24//! user code without compiler support.
25//!
26//! # Volatiles
27//!
28//! The volatile intrinsics provide operations intended to act on I/O
29//! memory, which are guaranteed to not be reordered by the compiler
30//! across other volatile intrinsics. See [`read_volatile`][ptr::read_volatile]
31//! and [`write_volatile`][ptr::write_volatile].
32//!
33//! # Atomics
34//!
35//! The atomic intrinsics provide common atomic operations on machine
36//! words, with multiple possible memory orderings. See the
37//! [atomic types][atomic] docs for details.
38//!
39//! # Unwinding
40//!
41//! Rust intrinsics may, in general, unwind. If an intrinsic can never unwind, add the
42//! `#[rustc_nounwind]` attribute so that the compiler can make use of this fact.
43//!
44//! However, even for intrinsics that may unwind, rustc assumes that a Rust intrinsics will never
45//! initiate a foreign (non-Rust) unwind, and thus for panic=abort we can always assume that these
46//! intrinsics cannot unwind.
47
48#![unstable(
49    feature = "core_intrinsics",
50    reason = "intrinsics are unlikely to ever be stabilized, instead \
51                      they should be used through stabilized interfaces \
52                      in the rest of the standard library",
53    issue = "none"
54)]
55
56#[cfg(not(feature = "ferrocene_subset"))]
57use crate::ffi::va_list::{VaArgSafe, VaList};
58use crate::marker::{ConstParamTy, DiscriminantKind, PointeeSized, Tuple};
59use crate::{mem, ptr};
60
61mod bounds;
62pub mod fallback;
63#[cfg(not(feature = "ferrocene_subset"))]
64pub mod gpu;
65#[cfg(not(feature = "ferrocene_subset"))]
66pub mod mir;
67pub mod simd;
68
69// These imports are used for simplifying intra-doc links
70#[allow(unused_imports)]
71#[cfg(all(target_has_atomic = "8", target_has_atomic = "32", target_has_atomic = "ptr"))]
72#[cfg(not(feature = "ferrocene_subset"))]
73use crate::sync::atomic::{self, AtomicBool, AtomicI32, AtomicIsize, AtomicU32, Ordering};
74
75/// A type for atomic ordering parameters for intrinsics. This is a separate type from
76/// `atomic::Ordering` so that we can make it `ConstParamTy` and fix the values used here without a
77/// risk of leaking that to stable code.
78#[allow(missing_docs)]
79#[derive(Debug, ConstParamTy, PartialEq, Eq)]
80pub enum AtomicOrdering {
81    // These values must match the compiler's `AtomicOrdering` defined in
82    // `rustc_middle/src/ty/consts/int.rs`!
83    Relaxed = 0,
84    Release = 1,
85    Acquire = 2,
86    AcqRel = 3,
87    SeqCst = 4,
88}
89
90// N.B., these intrinsics take raw pointers because they mutate aliased
91// memory, which is not valid for either `&` or `&mut`.
92
93/// Stores a value if the current value is the same as the `old` value.
94/// `T` must be an integer or pointer type.
95///
96/// The stabilized version of this intrinsic is available on the
97/// [`atomic`] types via the `compare_exchange` method.
98/// For example, [`AtomicBool::compare_exchange`].
99#[rustc_intrinsic]
100#[rustc_nounwind]
101pub unsafe fn atomic_cxchg<
102    T: Copy,
103    const ORD_SUCC: AtomicOrdering,
104    const ORD_FAIL: AtomicOrdering,
105>(
106    dst: *mut T,
107    old: T,
108    src: T,
109) -> (T, bool);
110
111/// Stores a value if the current value is the same as the `old` value.
112/// `T` must be an integer or pointer type. The comparison may spuriously fail.
113///
114/// The stabilized version of this intrinsic is available on the
115/// [`atomic`] types via the `compare_exchange_weak` method.
116/// For example, [`AtomicBool::compare_exchange_weak`].
117#[rustc_intrinsic]
118#[rustc_nounwind]
119pub unsafe fn atomic_cxchgweak<
120    T: Copy,
121    const ORD_SUCC: AtomicOrdering,
122    const ORD_FAIL: AtomicOrdering,
123>(
124    _dst: *mut T,
125    _old: T,
126    _src: T,
127) -> (T, bool);
128
129/// Loads the current value of the pointer.
130/// `T` must be an integer or pointer type.
131///
132/// The stabilized version of this intrinsic is available on the
133/// [`atomic`] types via the `load` method. For example, [`AtomicBool::load`].
134#[rustc_intrinsic]
135#[rustc_nounwind]
136pub unsafe fn atomic_load<T: Copy, const ORD: AtomicOrdering>(src: *const T) -> T;
137
138/// Stores the value at the specified memory location.
139/// `T` must be an integer or pointer type.
140///
141/// The stabilized version of this intrinsic is available on the
142/// [`atomic`] types via the `store` method. For example, [`AtomicBool::store`].
143#[rustc_intrinsic]
144#[rustc_nounwind]
145pub unsafe fn atomic_store<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, val: T);
146
147/// Stores the value at the specified memory location, returning the old value.
148/// `T` must be an integer or pointer type.
149///
150/// The stabilized version of this intrinsic is available on the
151/// [`atomic`] types via the `swap` method. For example, [`AtomicBool::swap`].
152#[rustc_intrinsic]
153#[rustc_nounwind]
154pub unsafe fn atomic_xchg<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
155
156/// Adds to the current value, returning the previous value.
157/// `T` must be an integer or pointer type.
158/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
159///
160/// The stabilized version of this intrinsic is available on the
161/// [`atomic`] types via the `fetch_add` method. For example, [`AtomicIsize::fetch_add`].
162#[rustc_intrinsic]
163#[rustc_nounwind]
164pub unsafe fn atomic_xadd<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
165
166/// Subtract from the current value, returning the previous value.
167/// `T` must be an integer or pointer type.
168/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
169///
170/// The stabilized version of this intrinsic is available on the
171/// [`atomic`] types via the `fetch_sub` method. For example, [`AtomicIsize::fetch_sub`].
172#[rustc_intrinsic]
173#[rustc_nounwind]
174pub unsafe fn atomic_xsub<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
175
176/// Bitwise and with the current value, returning the previous value.
177/// `T` must be an integer or pointer type.
178/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
179///
180/// The stabilized version of this intrinsic is available on the
181/// [`atomic`] types via the `fetch_and` method. For example, [`AtomicBool::fetch_and`].
182#[rustc_intrinsic]
183#[rustc_nounwind]
184pub unsafe fn atomic_and<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
185
186/// Bitwise nand with the current value, returning the previous value.
187/// `T` must be an integer or pointer type.
188/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
189///
190/// The stabilized version of this intrinsic is available on the
191/// [`AtomicBool`] type via the `fetch_nand` method. For example, [`AtomicBool::fetch_nand`].
192#[rustc_intrinsic]
193#[rustc_nounwind]
194pub unsafe fn atomic_nand<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
195
196/// Bitwise or with the current value, returning the previous value.
197/// `T` must be an integer or pointer type.
198/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
199///
200/// The stabilized version of this intrinsic is available on the
201/// [`atomic`] types via the `fetch_or` method. For example, [`AtomicBool::fetch_or`].
202#[rustc_intrinsic]
203#[rustc_nounwind]
204pub unsafe fn atomic_or<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
205
206/// Bitwise xor with the current value, returning the previous value.
207/// `T` must be an integer or pointer type.
208/// `U` must be the same as `T` if that is an integer type, or `usize` if `T` is a pointer type.
209///
210/// The stabilized version of this intrinsic is available on the
211/// [`atomic`] types via the `fetch_xor` method. For example, [`AtomicBool::fetch_xor`].
212#[rustc_intrinsic]
213#[rustc_nounwind]
214pub unsafe fn atomic_xor<T: Copy, U: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: U) -> T;
215
216/// Maximum with the current value using a signed comparison.
217/// `T` must be a signed integer type.
218///
219/// The stabilized version of this intrinsic is available on the
220/// [`atomic`] signed integer types via the `fetch_max` method. For example, [`AtomicI32::fetch_max`].
221#[rustc_intrinsic]
222#[rustc_nounwind]
223#[cfg(not(feature = "ferrocene_subset"))]
224pub unsafe fn atomic_max<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
225
226/// Minimum with the current value using a signed comparison.
227/// `T` must be a signed integer type.
228///
229/// The stabilized version of this intrinsic is available on the
230/// [`atomic`] signed integer types via the `fetch_min` method. For example, [`AtomicI32::fetch_min`].
231#[rustc_intrinsic]
232#[rustc_nounwind]
233#[cfg(not(feature = "ferrocene_subset"))]
234pub unsafe fn atomic_min<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
235
236/// Minimum with the current value using an unsigned comparison.
237/// `T` must be an unsigned integer type.
238///
239/// The stabilized version of this intrinsic is available on the
240/// [`atomic`] unsigned integer types via the `fetch_min` method. For example, [`AtomicU32::fetch_min`].
241#[rustc_intrinsic]
242#[rustc_nounwind]
243pub unsafe fn atomic_umin<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
244
245/// Maximum with the current value using an unsigned comparison.
246/// `T` must be an unsigned integer type.
247///
248/// The stabilized version of this intrinsic is available on the
249/// [`atomic`] unsigned integer types via the `fetch_max` method. For example, [`AtomicU32::fetch_max`].
250#[rustc_intrinsic]
251#[rustc_nounwind]
252pub unsafe fn atomic_umax<T: Copy, const ORD: AtomicOrdering>(dst: *mut T, src: T) -> T;
253
254/// An atomic fence.
255///
256/// The stabilized version of this intrinsic is available in
257/// [`atomic::fence`].
258#[rustc_intrinsic]
259#[rustc_nounwind]
260pub unsafe fn atomic_fence<const ORD: AtomicOrdering>();
261
262/// An atomic fence for synchronization within a single thread.
263///
264/// The stabilized version of this intrinsic is available in
265/// [`atomic::compiler_fence`].
266#[rustc_intrinsic]
267#[rustc_nounwind]
268pub unsafe fn atomic_singlethreadfence<const ORD: AtomicOrdering>();
269
270/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
271/// for the given address if supported; otherwise, it is a no-op.
272/// Prefetches have no effect on the behavior of the program but can change its performance
273/// characteristics.
274///
275/// The `LOCALITY` argument is a temporal locality specifier ranging from (0) - no locality,
276/// to (3) - extremely local keep in cache.
277///
278/// This intrinsic does not have a stable counterpart.
279#[rustc_intrinsic]
280#[rustc_nounwind]
281#[miri::intrinsic_fallback_is_spec]
282#[cfg(not(feature = "ferrocene_subset"))]
283pub const fn prefetch_read_data<T, const LOCALITY: i32>(data: *const T) {
284    // This operation is a no-op, unless it is overridden by the backend.
285    let _ = data;
286}
287
288/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
289/// for the given address if supported; otherwise, it is a no-op.
290/// Prefetches have no effect on the behavior of the program but can change its performance
291/// characteristics.
292///
293/// The `LOCALITY` argument is a temporal locality specifier ranging from (0) - no locality,
294/// to (3) - extremely local keep in cache.
295///
296/// This intrinsic does not have a stable counterpart.
297#[cfg(not(feature = "ferrocene_subset"))]
298#[rustc_intrinsic]
299#[rustc_nounwind]
300#[miri::intrinsic_fallback_is_spec]
301pub const fn prefetch_write_data<T, const LOCALITY: i32>(data: *const T) {
302    // This operation is a no-op, unless it is overridden by the backend.
303    let _ = data;
304}
305
306/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
307/// for the given address if supported; otherwise, it is a no-op.
308/// Prefetches have no effect on the behavior of the program but can change its performance
309/// characteristics.
310///
311/// The `LOCALITY` argument is a temporal locality specifier ranging from (0) - no locality,
312/// to (3) - extremely local keep in cache.
313///
314/// This intrinsic does not have a stable counterpart.
315#[rustc_intrinsic]
316#[rustc_nounwind]
317#[miri::intrinsic_fallback_is_spec]
318#[cfg(not(feature = "ferrocene_subset"))]
319pub const fn prefetch_read_instruction<T, const LOCALITY: i32>(data: *const T) {
320    // This operation is a no-op, unless it is overridden by the backend.
321    let _ = data;
322}
323
324/// The `prefetch` intrinsic is a hint to the code generator to insert a prefetch instruction
325/// for the given address if supported; otherwise, it is a no-op.
326/// Prefetches have no effect on the behavior of the program but can change its performance
327/// characteristics.
328///
329/// The `LOCALITY` argument is a temporal locality specifier ranging from (0) - no locality,
330/// to (3) - extremely local keep in cache.
331///
332/// This intrinsic does not have a stable counterpart.
333#[rustc_intrinsic]
334#[rustc_nounwind]
335#[miri::intrinsic_fallback_is_spec]
336#[cfg(not(feature = "ferrocene_subset"))]
337pub const fn prefetch_write_instruction<T, const LOCALITY: i32>(data: *const T) {
338    // This operation is a no-op, unless it is overridden by the backend.
339    let _ = data;
340}
341
342/// Executes a breakpoint trap, for inspection by a debugger.
343///
344/// This intrinsic does not have a stable counterpart.
345#[rustc_intrinsic]
346#[rustc_nounwind]
347#[cfg(not(feature = "ferrocene_subset"))]
348pub fn breakpoint();
349
350/// Magic intrinsic that derives its meaning from attributes
351/// attached to the function.
352///
353/// For example, dataflow uses this to inject static assertions so
354/// that `rustc_peek(potentially_uninitialized)` would actually
355/// double-check that dataflow did indeed compute that it is
356/// uninitialized at that point in the control flow.
357///
358/// This intrinsic should not be used outside of the compiler.
359#[rustc_nounwind]
360#[rustc_intrinsic]
361#[cfg(not(feature = "ferrocene_subset"))]
362pub fn rustc_peek<T>(_: T) -> T;
363
364/// Aborts the execution of the process.
365///
366/// Note that, unlike most intrinsics, this is safe to call;
367/// it does not require an `unsafe` block.
368/// Therefore, implementations must not require the user to uphold
369/// any safety invariants.
370///
371/// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible,
372/// as its behavior is more user-friendly and more stable.
373///
374/// The current implementation of `intrinsics::abort` is to invoke an invalid instruction,
375/// on most platforms.
376/// On Unix, the
377/// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
378/// `SIGBUS`.  The precise behavior is not guaranteed and not stable.
379#[rustc_nounwind]
380#[rustc_intrinsic]
381pub fn abort() -> !;
382
383/// Informs the optimizer that this point in the code is not reachable,
384/// enabling further optimizations.
385///
386/// N.B., this is very different from the `unreachable!()` macro: Unlike the
387/// macro, which panics when it is executed, it is *undefined behavior* to
388/// reach code marked with this function.
389///
390/// The stabilized version of this intrinsic is [`core::hint::unreachable_unchecked`].
391#[rustc_intrinsic_const_stable_indirect]
392#[rustc_nounwind]
393#[rustc_intrinsic]
394pub const unsafe fn unreachable() -> !;
395
396/// Informs the optimizer that a condition is always true.
397/// If the condition is false, the behavior is undefined.
398///
399/// No code is generated for this intrinsic, but the optimizer will try
400/// to preserve it (and its condition) between passes, which may interfere
401/// with optimization of surrounding code and reduce performance. It should
402/// not be used if the invariant can be discovered by the optimizer on its
403/// own, or if it does not enable any significant optimizations.
404///
405/// The stabilized version of this intrinsic is [`core::hint::assert_unchecked`].
406#[rustc_intrinsic_const_stable_indirect]
407#[rustc_nounwind]
408#[unstable(feature = "core_intrinsics", issue = "none")]
409#[rustc_intrinsic]
410#[ferrocene::annotation(
411    "Cannot be covered, since the purpose of the function is to never receive a `b` that is `false`, and if it does it will kill the process."
412)]
413pub const unsafe fn assume(b: bool) {
414    if !b {
415        // SAFETY: the caller must guarantee the argument is never `false`
416        unsafe { unreachable() }
417    }
418}
419
420/// Hints to the compiler that current code path is cold.
421///
422/// Note that, unlike most intrinsics, this is safe to call;
423/// it does not require an `unsafe` block.
424/// Therefore, implementations must not require the user to uphold
425/// any safety invariants.
426///
427/// The stabilized version of this intrinsic is [`core::hint::cold_path`].
428#[rustc_intrinsic]
429#[rustc_nounwind]
430#[miri::intrinsic_fallback_is_spec]
431#[cold]
432pub const fn cold_path() {}
433
434/// Hints to the compiler that branch condition is likely to be true.
435/// Returns the value passed to it.
436///
437/// Any use other than with `if` statements will probably not have an effect.
438///
439/// Note that, unlike most intrinsics, this is safe to call;
440/// it does not require an `unsafe` block.
441/// Therefore, implementations must not require the user to uphold
442/// any safety invariants.
443///
444/// This intrinsic does not have a stable counterpart.
445#[unstable(feature = "core_intrinsics", issue = "none")]
446#[rustc_nounwind]
447#[inline(always)]
448pub const fn likely(b: bool) -> bool {
449    if b {
450        true
451    } else {
452        cold_path();
453        false
454    }
455}
456
457/// Hints to the compiler that branch condition is likely to be false.
458/// Returns the value passed to it.
459///
460/// Any use other than with `if` statements will probably not have an effect.
461///
462/// Note that, unlike most intrinsics, this is safe to call;
463/// it does not require an `unsafe` block.
464/// Therefore, implementations must not require the user to uphold
465/// any safety invariants.
466///
467/// This intrinsic does not have a stable counterpart.
468#[unstable(feature = "core_intrinsics", issue = "none")]
469#[rustc_nounwind]
470#[inline(always)]
471pub const fn unlikely(b: bool) -> bool {
472    if b {
473        cold_path();
474        true
475    } else {
476        false
477    }
478}
479
480/// Returns either `true_val` or `false_val` depending on condition `b` with a
481/// hint to the compiler that this condition is unlikely to be correctly
482/// predicted by a CPU's branch predictor (e.g. a binary search).
483///
484/// This is otherwise functionally equivalent to `if b { true_val } else { false_val }`.
485///
486/// Note that, unlike most intrinsics, this is safe to call;
487/// it does not require an `unsafe` block.
488/// Therefore, implementations must not require the user to uphold
489/// any safety invariants.
490///
491/// The public form of this intrinsic is [`core::hint::select_unpredictable`].
492/// However unlike the public form, the intrinsic will not drop the value that
493/// is not selected.
494#[unstable(feature = "core_intrinsics", issue = "none")]
495#[rustc_const_unstable(feature = "const_select_unpredictable", issue = "145938")]
496#[rustc_intrinsic]
497#[rustc_nounwind]
498#[miri::intrinsic_fallback_is_spec]
499#[inline]
500pub const fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
501    if b {
502        forget(false_val);
503        true_val
504    } else {
505        forget(true_val);
506        false_val
507    }
508}
509
510/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
511/// This will statically either panic, or do nothing. It does not *guarantee* to ever panic,
512/// and should only be called if an assertion failure will imply language UB in the following code.
513///
514/// This intrinsic does not have a stable counterpart.
515#[rustc_intrinsic_const_stable_indirect]
516#[rustc_nounwind]
517#[rustc_intrinsic]
518pub const fn assert_inhabited<T>();
519
520/// A guard for unsafe functions that cannot ever be executed if `T` does not permit
521/// zero-initialization: This will statically either panic, or do nothing. It does not *guarantee*
522/// to ever panic, and should only be called if an assertion failure will imply language UB in the
523/// following code.
524///
525/// This intrinsic does not have a stable counterpart.
526#[rustc_intrinsic_const_stable_indirect]
527#[rustc_nounwind]
528#[rustc_intrinsic]
529pub const fn assert_zero_valid<T>();
530
531/// A guard for `std::mem::uninitialized`. This will statically either panic, or do nothing. It does
532/// not *guarantee* to ever panic, and should only be called if an assertion failure will imply
533/// language UB in the following code.
534///
535/// This intrinsic does not have a stable counterpart.
536#[rustc_intrinsic_const_stable_indirect]
537#[rustc_nounwind]
538#[rustc_intrinsic]
539#[cfg(not(feature = "ferrocene_subset"))]
540pub const fn assert_mem_uninitialized_valid<T>();
541
542/// Gets a reference to a static `Location` indicating where it was called.
543///
544/// Note that, unlike most intrinsics, this is safe to call;
545/// it does not require an `unsafe` block.
546/// Therefore, implementations must not require the user to uphold
547/// any safety invariants.
548///
549/// Consider using [`core::panic::Location::caller`] instead.
550#[rustc_intrinsic_const_stable_indirect]
551#[rustc_nounwind]
552#[rustc_intrinsic]
553pub const fn caller_location() -> &'static crate::panic::Location<'static>;
554
555/// Moves a value out of scope without running drop glue.
556///
557/// This exists solely for [`crate::mem::forget_unsized`]; normal `forget` uses
558/// `ManuallyDrop` instead.
559///
560/// Note that, unlike most intrinsics, this is safe to call;
561/// it does not require an `unsafe` block.
562/// Therefore, implementations must not require the user to uphold
563/// any safety invariants.
564#[rustc_intrinsic_const_stable_indirect]
565#[rustc_nounwind]
566#[rustc_intrinsic]
567pub const fn forget<T: ?Sized>(_: T);
568
569/// Reinterprets the bits of a value of one type as another type.
570///
571/// Both types must have the same size. Compilation will fail if this is not guaranteed.
572///
573/// `transmute` is semantically equivalent to a bitwise move of one type
574/// into another. It copies the bits from the source value into the
575/// destination value, then forgets the original. Note that source and destination
576/// are passed by-value, which means if `Src` or `Dst` contain padding, that padding
577/// is *not* guaranteed to be preserved by `transmute`.
578///
579/// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at
580/// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler
581/// will generate code *assuming that you, the programmer, ensure that there will never be
582/// undefined behavior*. It is therefore your responsibility to guarantee that every value
583/// passed to `transmute` is valid at both types `Src` and `Dst`. Failing to uphold this condition
584/// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
585/// unsafe**. `transmute` should be the absolute last resort.
586///
587/// Because `transmute` is a by-value operation, alignment of the *transmuted values
588/// themselves* is not a concern. As with any other function, the compiler already ensures
589/// both `Src` and `Dst` are properly aligned. However, when transmuting values that *point
590/// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
591/// alignment of the pointed-to values.
592///
593/// The [nomicon](../../nomicon/transmutes.html) has additional documentation.
594///
595/// [ub]: ../../reference/behavior-considered-undefined.html
596///
597/// # Transmutation between pointers and integers
598///
599/// Special care has to be taken when transmuting between pointers and integers, e.g.
600/// transmuting between `*const ()` and `usize`.
601///
602/// Transmuting *pointers to integers* in a `const` context is [undefined behavior][ub], unless
603/// the pointer was originally created *from* an integer. (That includes this function
604/// specifically, integer-to-pointer casts, and helpers like [`dangling`][crate::ptr::dangling],
605/// but also semantically-equivalent conversions such as punning through `repr(C)` union
606/// fields.) Any attempt to use the resulting value for integer operations will abort
607/// const-evaluation. (And even outside `const`, such transmutation is touching on many
608/// unspecified aspects of the Rust memory model and should be avoided. See below for
609/// alternatives.)
610///
611/// Transmuting *integers to pointers* is a largely unspecified operation. It is likely *not*
612/// equivalent to an `as` cast. Doing non-zero-sized memory accesses with a pointer constructed
613/// this way is currently considered undefined behavior.
614///
615/// All this also applies when the integer is nested inside an array, tuple, struct, or enum.
616/// However, `MaybeUninit<usize>` is not considered an integer type for the purpose of this
617/// section. Transmuting `*const ()` to `MaybeUninit<usize>` is fine---but then calling
618/// `assume_init()` on that result is considered as completing the pointer-to-integer transmute
619/// and thus runs into the issues discussed above.
620///
621/// In particular, doing a pointer-to-integer-to-pointer roundtrip via `transmute` is *not* a
622/// lossless process. If you want to round-trip a pointer through an integer in a way that you
623/// can get back the original pointer, you need to use `as` casts, or replace the integer type
624/// by `MaybeUninit<$int>` (and never call `assume_init()`). If you are looking for a way to
625/// store data of arbitrary type, also use `MaybeUninit<T>` (that will also handle uninitialized
626/// memory due to padding). If you specifically need to store something that is "either an
627/// integer or a pointer", use `*mut ()`: integers can be converted to pointers and back without
628/// any loss (via `as` casts or via `transmute`).
629///
630/// # Examples
631///
632/// There are a few things that `transmute` is really useful for.
633///
634/// Turning a pointer into a function pointer. This is *not* portable to
635/// machines where function pointers and data pointers have different sizes.
636///
637/// ```
638/// fn foo() -> i32 {
639///     0
640/// }
641/// // Crucially, we `as`-cast to a raw pointer before `transmute`ing to a function pointer.
642/// // This avoids an integer-to-pointer `transmute`, which can be problematic.
643/// // Transmuting between raw pointers and function pointers (i.e., two pointer types) is fine.
644/// let pointer = foo as fn() -> i32 as *const ();
645/// let function = unsafe {
646///     std::mem::transmute::<*const (), fn() -> i32>(pointer)
647/// };
648/// assert_eq!(function(), 0);
649/// ```
650///
651/// Extending a lifetime, or shortening an invariant lifetime. This is
652/// advanced, very unsafe Rust!
653///
654/// ```
655/// struct R<'a>(&'a i32);
656/// unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
657///     unsafe { std::mem::transmute::<R<'b>, R<'static>>(r) }
658/// }
659///
660/// unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>)
661///                                              -> &'b mut R<'c> {
662///     unsafe { std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r) }
663/// }
664/// ```
665///
666/// # Alternatives
667///
668/// Don't despair: many uses of `transmute` can be achieved through other means.
669/// Below are common applications of `transmute` which can be replaced with safer
670/// constructs.
671///
672/// Turning raw bytes (`[u8; SZ]`) into `u32`, `f64`, etc.:
673///
674/// ```
675/// # #![allow(unnecessary_transmutes)]
676/// let raw_bytes = [0x78, 0x56, 0x34, 0x12];
677///
678/// let num = unsafe {
679///     std::mem::transmute::<[u8; 4], u32>(raw_bytes)
680/// };
681///
682/// // use `u32::from_ne_bytes` instead
683/// let num = u32::from_ne_bytes(raw_bytes);
684/// // or use `u32::from_le_bytes` or `u32::from_be_bytes` to specify the endianness
685/// let num = u32::from_le_bytes(raw_bytes);
686/// assert_eq!(num, 0x12345678);
687/// let num = u32::from_be_bytes(raw_bytes);
688/// assert_eq!(num, 0x78563412);
689/// ```
690///
691/// Turning a pointer into a `usize`:
692///
693/// ```no_run
694/// let ptr = &0;
695/// let ptr_num_transmute = unsafe {
696///     std::mem::transmute::<&i32, usize>(ptr)
697/// };
698///
699/// // Use an `as` cast instead
700/// let ptr_num_cast = ptr as *const i32 as usize;
701/// ```
702///
703/// Note that using `transmute` to turn a pointer to a `usize` is (as noted above) [undefined
704/// behavior][ub] in `const` contexts. Also outside of consts, this operation might not behave
705/// as expected -- this is touching on many unspecified aspects of the Rust memory model.
706/// Depending on what the code is doing, the following alternatives are preferable to
707/// pointer-to-integer transmutation:
708/// - If the code just wants to store data of arbitrary type in some buffer and needs to pick a
709///   type for that buffer, it can use [`MaybeUninit`][crate::mem::MaybeUninit].
710/// - If the code actually wants to work on the address the pointer points to, it can use `as`
711///   casts or [`ptr.addr()`][pointer::addr].
712///
713/// Turning a `*mut T` into a `&mut T`:
714///
715/// ```
716/// let ptr: *mut i32 = &mut 0;
717/// let ref_transmuted = unsafe {
718///     std::mem::transmute::<*mut i32, &mut i32>(ptr)
719/// };
720///
721/// // Use a reborrow instead
722/// let ref_casted = unsafe { &mut *ptr };
723/// ```
724///
725/// Turning a `&mut T` into a `&mut U`:
726///
727/// ```
728/// let ptr = &mut 0;
729/// let val_transmuted = unsafe {
730///     std::mem::transmute::<&mut i32, &mut u32>(ptr)
731/// };
732///
733/// // Now, put together `as` and reborrowing - note the chaining of `as`
734/// // `as` is not transitive
735/// let val_casts = unsafe { &mut *(ptr as *mut i32 as *mut u32) };
736/// ```
737///
738/// Turning a `&str` into a `&[u8]`:
739///
740/// ```
741/// // this is not a good way to do this.
742/// let slice = unsafe { std::mem::transmute::<&str, &[u8]>("Rust") };
743/// assert_eq!(slice, &[82, 117, 115, 116]);
744///
745/// // You could use `str::as_bytes`
746/// let slice = "Rust".as_bytes();
747/// assert_eq!(slice, &[82, 117, 115, 116]);
748///
749/// // Or, just use a byte string, if you have control over the string
750/// // literal
751/// assert_eq!(b"Rust", &[82, 117, 115, 116]);
752/// ```
753///
754/// Turning a `Vec<&T>` into a `Vec<Option<&T>>`.
755///
756/// To transmute the inner type of the contents of a container, you must make sure to not
757/// violate any of the container's invariants. For `Vec`, this means that both the size
758/// *and alignment* of the inner types have to match. Other containers might rely on the
759/// size of the type, alignment, or even the `TypeId`, in which case transmuting wouldn't
760/// be possible at all without violating the container invariants.
761///
762/// ```
763/// let store = [0, 1, 2, 3];
764/// let v_orig = store.iter().collect::<Vec<&i32>>();
765///
766/// // clone the vector as we will reuse them later
767/// let v_clone = v_orig.clone();
768///
769/// // Using transmute: this relies on the unspecified data layout of `Vec`, which is a
770/// // bad idea and could cause Undefined Behavior.
771/// // However, it is no-copy.
772/// let v_transmuted = unsafe {
773///     std::mem::transmute::<Vec<&i32>, Vec<Option<&i32>>>(v_clone)
774/// };
775///
776/// let v_clone = v_orig.clone();
777///
778/// // This is the suggested, safe way.
779/// // It may copy the entire vector into a new one though, but also may not.
780/// let v_collected = v_clone.into_iter()
781///                          .map(Some)
782///                          .collect::<Vec<Option<&i32>>>();
783///
784/// let v_clone = v_orig.clone();
785///
786/// // This is the proper no-copy, unsafe way of "transmuting" a `Vec`, without relying on the
787/// // data layout. Instead of literally calling `transmute`, we perform a pointer cast, but
788/// // in terms of converting the original inner type (`&i32`) to the new one (`Option<&i32>`),
789/// // this has all the same caveats. Besides the information provided above, also consult the
790/// // [`from_raw_parts`] documentation.
791/// let (ptr, len, capacity) = v_clone.into_raw_parts();
792/// let v_from_raw = unsafe {
793///     Vec::from_raw_parts(ptr.cast::<*mut Option<&i32>>(), len, capacity)
794/// };
795/// ```
796///
797/// [`from_raw_parts`]: ../../std/vec/struct.Vec.html#method.from_raw_parts
798///
799/// Implementing `split_at_mut`:
800///
801/// ```
802/// use std::{slice, mem};
803///
804/// // There are multiple ways to do this, and there are multiple problems
805/// // with the following (transmute) way.
806/// fn split_at_mut_transmute<T>(slice: &mut [T], mid: usize)
807///                              -> (&mut [T], &mut [T]) {
808///     let len = slice.len();
809///     assert!(mid <= len);
810///     unsafe {
811///         let slice2 = mem::transmute::<&mut [T], &mut [T]>(slice);
812///         // first: transmute is not type safe; all it checks is that T and
813///         // U are of the same size. Second, right here, you have two
814///         // mutable references pointing to the same memory.
815///         (&mut slice[0..mid], &mut slice2[mid..len])
816///     }
817/// }
818///
819/// // This gets rid of the type safety problems; `&mut *` will *only* give
820/// // you a `&mut T` from a `&mut T` or `*mut T`.
821/// fn split_at_mut_casts<T>(slice: &mut [T], mid: usize)
822///                          -> (&mut [T], &mut [T]) {
823///     let len = slice.len();
824///     assert!(mid <= len);
825///     unsafe {
826///         let slice2 = &mut *(slice as *mut [T]);
827///         // however, you still have two mutable references pointing to
828///         // the same memory.
829///         (&mut slice[0..mid], &mut slice2[mid..len])
830///     }
831/// }
832///
833/// // This is how the standard library does it. This is the best method, if
834/// // you need to do something like this
835/// fn split_at_stdlib<T>(slice: &mut [T], mid: usize)
836///                       -> (&mut [T], &mut [T]) {
837///     let len = slice.len();
838///     assert!(mid <= len);
839///     unsafe {
840///         let ptr = slice.as_mut_ptr();
841///         // This now has three mutable references pointing at the same
842///         // memory. `slice`, the rvalue ret.0, and the rvalue ret.1.
843///         // `slice` is never used after `let ptr = ...`, and so one can
844///         // treat it as "dead", and therefore, you only have two real
845///         // mutable slices.
846///         (slice::from_raw_parts_mut(ptr, mid),
847///          slice::from_raw_parts_mut(ptr.add(mid), len - mid))
848///     }
849/// }
850/// ```
851#[stable(feature = "rust1", since = "1.0.0")]
852#[rustc_allowed_through_unstable_modules = "import this function via `std::mem` instead"]
853#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
854#[rustc_diagnostic_item = "transmute"]
855#[rustc_nounwind]
856#[rustc_intrinsic]
857pub const unsafe fn transmute<Src, Dst>(src: Src) -> Dst;
858
859/// Like [`transmute`], but even less checked at compile-time: rather than
860/// giving an error for `size_of::<Src>() != size_of::<Dst>()`, it's
861/// **Undefined Behavior** at runtime.
862///
863/// Prefer normal `transmute` where possible, for the extra checking, since
864/// both do exactly the same thing at runtime, if they both compile.
865///
866/// This is not expected to ever be exposed directly to users, rather it
867/// may eventually be exposed through some more-constrained API.
868#[rustc_intrinsic_const_stable_indirect]
869#[rustc_nounwind]
870#[rustc_intrinsic]
871pub const unsafe fn transmute_unchecked<Src, Dst>(src: Src) -> Dst;
872
873/// Returns `true` if the actual type given as `T` requires drop
874/// glue; returns `false` if the actual type provided for `T`
875/// implements `Copy`.
876///
877/// If the actual type neither requires drop glue nor implements
878/// `Copy`, then the return value of this function is unspecified.
879///
880/// Note that, unlike most intrinsics, this can only be called at compile-time
881/// as backends do not have an implementation for it. The only caller (its
882/// stable counterpart) wraps this intrinsic call in a `const` block so that
883/// backends only see an evaluated constant.
884///
885/// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
886#[rustc_intrinsic_const_stable_indirect]
887#[rustc_nounwind]
888#[rustc_intrinsic]
889pub const fn needs_drop<T: ?Sized>() -> bool;
890
891/// Calculates the offset from a pointer.
892///
893/// This is implemented as an intrinsic to avoid converting to and from an
894/// integer, since the conversion would throw away aliasing information.
895///
896/// This can only be used with `Ptr` as a raw pointer type (`*mut` or `*const`)
897/// to a `Sized` pointee and with `Delta` as `usize` or `isize`.  Any other
898/// instantiations may arbitrarily misbehave, and that's *not* a compiler bug.
899///
900/// # Safety
901///
902/// If the computed offset is non-zero, then both the starting and resulting pointer must be
903/// either in bounds or at the end of an allocation. If either pointer is out
904/// of bounds or arithmetic overflow occurs then this operation is undefined behavior.
905///
906/// The stabilized version of this intrinsic is [`pointer::offset`].
907#[must_use = "returns a new pointer rather than modifying its argument"]
908#[rustc_intrinsic_const_stable_indirect]
909#[rustc_nounwind]
910#[rustc_intrinsic]
911pub const unsafe fn offset<Ptr: bounds::BuiltinDeref, Delta>(dst: Ptr, offset: Delta) -> Ptr;
912
913/// Calculates the offset from a pointer, potentially wrapping.
914///
915/// This is implemented as an intrinsic to avoid converting to and from an
916/// integer, since the conversion inhibits certain optimizations.
917///
918/// # Safety
919///
920/// Unlike the `offset` intrinsic, this intrinsic does not restrict the
921/// resulting pointer to point into or at the end of an allocated
922/// object, and it wraps with two's complement arithmetic. The resulting
923/// value is not necessarily valid to be used to actually access memory.
924///
925/// The stabilized version of this intrinsic is [`pointer::wrapping_offset`].
926#[must_use = "returns a new pointer rather than modifying its argument"]
927#[rustc_intrinsic_const_stable_indirect]
928#[rustc_nounwind]
929#[rustc_intrinsic]
930pub const unsafe fn arith_offset<T>(dst: *const T, offset: isize) -> *const T;
931
932/// Projects to the `index`-th element of `slice_ptr`, as the same kind of pointer
933/// as the slice was provided -- so `&mut [T] → &mut T`, `&[T] → &T`,
934/// `*mut [T] → *mut T`, or `*const [T] → *const T` -- without a bounds check.
935///
936/// This is exposed via `<usize as SliceIndex>::get(_unchecked)(_mut)`,
937/// and isn't intended to be used elsewhere.
938///
939/// Expands in MIR to `{&, &mut, &raw const, &raw mut} (*slice_ptr)[index]`,
940/// depending on the types involved, so no backend support is needed.
941///
942/// # Safety
943///
944/// - `index < PtrMetadata(slice_ptr)`, so the indexing is in-bounds for the slice
945/// - the resulting offsetting is in-bounds of the allocation, which is
946///   always the case for references, but needs to be upheld manually for pointers
947#[rustc_nounwind]
948#[rustc_intrinsic]
949pub const unsafe fn slice_get_unchecked<
950    ItemPtr: bounds::ChangePointee<[T], Pointee = T, Output = SlicePtr>,
951    SlicePtr,
952    T,
953>(
954    slice_ptr: SlicePtr,
955    index: usize,
956) -> ItemPtr;
957
958/// Masks out bits of the pointer according to a mask.
959///
960/// Note that, unlike most intrinsics, this is safe to call;
961/// it does not require an `unsafe` block.
962/// Therefore, implementations must not require the user to uphold
963/// any safety invariants.
964///
965/// Consider using [`pointer::mask`] instead.
966#[rustc_nounwind]
967#[rustc_intrinsic]
968#[cfg(not(feature = "ferrocene_subset"))]
969pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T;
970
971/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
972/// a size of `count` * `size_of::<T>()` and an alignment of `align_of::<T>()`.
973///
974/// This intrinsic does not have a stable counterpart.
975/// # Safety
976///
977/// The safety requirements are consistent with [`copy_nonoverlapping`]
978/// while the read and write behaviors are volatile,
979/// which means it will not be optimized out unless `_count` or `size_of::<T>()` is equal to zero.
980///
981/// [`copy_nonoverlapping`]: ptr::copy_nonoverlapping
982#[rustc_intrinsic]
983#[rustc_nounwind]
984#[cfg(not(feature = "ferrocene_subset"))]
985pub unsafe fn volatile_copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
986/// Equivalent to the appropriate `llvm.memmove.p0i8.0i8.*` intrinsic, with
987/// a size of `count * size_of::<T>()` and an alignment of `align_of::<T>()`.
988///
989/// The volatile parameter is set to `true`, so it will not be optimized out
990/// unless size is equal to zero.
991///
992/// This intrinsic does not have a stable counterpart.
993#[rustc_intrinsic]
994#[rustc_nounwind]
995#[cfg(not(feature = "ferrocene_subset"))]
996pub unsafe fn volatile_copy_memory<T>(dst: *mut T, src: *const T, count: usize);
997/// Equivalent to the appropriate `llvm.memset.p0i8.*` intrinsic, with a
998/// size of `count * size_of::<T>()` and an alignment of `align_of::<T>()`.
999///
1000/// This intrinsic does not have a stable counterpart.
1001/// # Safety
1002///
1003/// The safety requirements are consistent with [`write_bytes`] while the write behavior is volatile,
1004/// which means it will not be optimized out unless `_count` or `size_of::<T>()` is equal to zero.
1005///
1006/// [`write_bytes`]: ptr::write_bytes
1007#[rustc_intrinsic]
1008#[rustc_nounwind]
1009#[cfg(not(feature = "ferrocene_subset"))]
1010pub unsafe fn volatile_set_memory<T>(dst: *mut T, val: u8, count: usize);
1011
1012/// Performs a volatile load from the `src` pointer.
1013///
1014/// The stabilized version of this intrinsic is [`core::ptr::read_volatile`].
1015#[rustc_intrinsic]
1016#[rustc_nounwind]
1017pub unsafe fn volatile_load<T>(src: *const T) -> T;
1018/// Performs a volatile store to the `dst` pointer.
1019///
1020/// The stabilized version of this intrinsic is [`core::ptr::write_volatile`].
1021#[rustc_intrinsic]
1022#[rustc_nounwind]
1023pub unsafe fn volatile_store<T>(dst: *mut T, val: T);
1024
1025/// Performs a volatile load from the `src` pointer
1026/// The pointer is not required to be aligned.
1027///
1028/// This intrinsic does not have a stable counterpart.
1029#[rustc_intrinsic]
1030#[rustc_nounwind]
1031#[rustc_diagnostic_item = "intrinsics_unaligned_volatile_load"]
1032#[cfg(not(feature = "ferrocene_subset"))]
1033pub unsafe fn unaligned_volatile_load<T>(src: *const T) -> T;
1034/// Performs a volatile store to the `dst` pointer.
1035/// The pointer is not required to be aligned.
1036///
1037/// This intrinsic does not have a stable counterpart.
1038#[rustc_intrinsic]
1039#[rustc_nounwind]
1040#[rustc_diagnostic_item = "intrinsics_unaligned_volatile_store"]
1041#[cfg(not(feature = "ferrocene_subset"))]
1042pub unsafe fn unaligned_volatile_store<T>(dst: *mut T, val: T);
1043
1044/// Returns the square root of an `f16`
1045///
1046/// The stabilized version of this intrinsic is
1047/// [`f16::sqrt`](../../std/primitive.f16.html#method.sqrt)
1048#[rustc_intrinsic]
1049#[rustc_nounwind]
1050#[cfg(not(feature = "ferrocene_subset"))]
1051pub fn sqrtf16(x: f16) -> f16;
1052/// Returns the square root of an `f32`
1053///
1054/// The stabilized version of this intrinsic is
1055/// [`f32::sqrt`](../../std/primitive.f32.html#method.sqrt)
1056#[rustc_intrinsic]
1057#[rustc_nounwind]
1058pub fn sqrtf32(x: f32) -> f32;
1059/// Returns the square root of an `f64`
1060///
1061/// The stabilized version of this intrinsic is
1062/// [`f64::sqrt`](../../std/primitive.f64.html#method.sqrt)
1063#[rustc_intrinsic]
1064#[rustc_nounwind]
1065pub fn sqrtf64(x: f64) -> f64;
1066/// Returns the square root of an `f128`
1067///
1068/// The stabilized version of this intrinsic is
1069/// [`f128::sqrt`](../../std/primitive.f128.html#method.sqrt)
1070#[rustc_intrinsic]
1071#[rustc_nounwind]
1072#[cfg(not(feature = "ferrocene_subset"))]
1073pub fn sqrtf128(x: f128) -> f128;
1074
1075/// Raises an `f16` to an integer power.
1076///
1077/// The stabilized version of this intrinsic is
1078/// [`f16::powi`](../../std/primitive.f16.html#method.powi)
1079#[rustc_intrinsic]
1080#[rustc_nounwind]
1081#[cfg(not(feature = "ferrocene_subset"))]
1082pub fn powif16(a: f16, x: i32) -> f16;
1083/// Raises an `f32` to an integer power.
1084///
1085/// The stabilized version of this intrinsic is
1086/// [`f32::powi`](../../std/primitive.f32.html#method.powi)
1087#[rustc_intrinsic]
1088#[rustc_nounwind]
1089#[cfg(not(feature = "ferrocene_subset"))]
1090pub fn powif32(a: f32, x: i32) -> f32;
1091/// Raises an `f64` to an integer power.
1092///
1093/// The stabilized version of this intrinsic is
1094/// [`f64::powi`](../../std/primitive.f64.html#method.powi)
1095#[rustc_intrinsic]
1096#[rustc_nounwind]
1097#[cfg(not(feature = "ferrocene_subset"))]
1098pub fn powif64(a: f64, x: i32) -> f64;
1099/// Raises an `f128` to an integer power.
1100///
1101/// The stabilized version of this intrinsic is
1102/// [`f128::powi`](../../std/primitive.f128.html#method.powi)
1103#[rustc_intrinsic]
1104#[rustc_nounwind]
1105#[cfg(not(feature = "ferrocene_subset"))]
1106pub fn powif128(a: f128, x: i32) -> f128;
1107
1108/// Returns the sine of an `f16`.
1109///
1110/// The stabilized version of this intrinsic is
1111/// [`f16::sin`](../../std/primitive.f16.html#method.sin)
1112#[rustc_intrinsic]
1113#[rustc_nounwind]
1114#[cfg(not(feature = "ferrocene_subset"))]
1115pub fn sinf16(x: f16) -> f16;
1116/// Returns the sine of an `f32`.
1117///
1118/// The stabilized version of this intrinsic is
1119/// [`f32::sin`](../../std/primitive.f32.html#method.sin)
1120#[rustc_intrinsic]
1121#[rustc_nounwind]
1122#[cfg(not(feature = "ferrocene_subset"))]
1123pub fn sinf32(x: f32) -> f32;
1124/// Returns the sine of an `f64`.
1125///
1126/// The stabilized version of this intrinsic is
1127/// [`f64::sin`](../../std/primitive.f64.html#method.sin)
1128#[rustc_intrinsic]
1129#[rustc_nounwind]
1130#[cfg(not(feature = "ferrocene_subset"))]
1131pub fn sinf64(x: f64) -> f64;
1132/// Returns the sine of an `f128`.
1133///
1134/// The stabilized version of this intrinsic is
1135/// [`f128::sin`](../../std/primitive.f128.html#method.sin)
1136#[rustc_intrinsic]
1137#[rustc_nounwind]
1138#[cfg(not(feature = "ferrocene_subset"))]
1139pub fn sinf128(x: f128) -> f128;
1140
1141/// Returns the cosine of an `f16`.
1142///
1143/// The stabilized version of this intrinsic is
1144/// [`f16::cos`](../../std/primitive.f16.html#method.cos)
1145#[rustc_intrinsic]
1146#[rustc_nounwind]
1147#[cfg(not(feature = "ferrocene_subset"))]
1148pub fn cosf16(x: f16) -> f16;
1149/// Returns the cosine of an `f32`.
1150///
1151/// The stabilized version of this intrinsic is
1152/// [`f32::cos`](../../std/primitive.f32.html#method.cos)
1153#[rustc_intrinsic]
1154#[rustc_nounwind]
1155#[cfg(not(feature = "ferrocene_subset"))]
1156pub fn cosf32(x: f32) -> f32;
1157/// Returns the cosine of an `f64`.
1158///
1159/// The stabilized version of this intrinsic is
1160/// [`f64::cos`](../../std/primitive.f64.html#method.cos)
1161#[rustc_intrinsic]
1162#[rustc_nounwind]
1163#[cfg(not(feature = "ferrocene_subset"))]
1164pub fn cosf64(x: f64) -> f64;
1165/// Returns the cosine of an `f128`.
1166///
1167/// The stabilized version of this intrinsic is
1168/// [`f128::cos`](../../std/primitive.f128.html#method.cos)
1169#[rustc_intrinsic]
1170#[rustc_nounwind]
1171#[cfg(not(feature = "ferrocene_subset"))]
1172pub fn cosf128(x: f128) -> f128;
1173
1174/// Raises an `f16` to an `f16` power.
1175///
1176/// The stabilized version of this intrinsic is
1177/// [`f16::powf`](../../std/primitive.f16.html#method.powf)
1178#[rustc_intrinsic]
1179#[rustc_nounwind]
1180#[cfg(not(feature = "ferrocene_subset"))]
1181pub fn powf16(a: f16, x: f16) -> f16;
1182/// Raises an `f32` to an `f32` power.
1183///
1184/// The stabilized version of this intrinsic is
1185/// [`f32::powf`](../../std/primitive.f32.html#method.powf)
1186#[rustc_intrinsic]
1187#[rustc_nounwind]
1188#[cfg(not(feature = "ferrocene_subset"))]
1189pub fn powf32(a: f32, x: f32) -> f32;
1190/// Raises an `f64` to an `f64` power.
1191///
1192/// The stabilized version of this intrinsic is
1193/// [`f64::powf`](../../std/primitive.f64.html#method.powf)
1194#[rustc_intrinsic]
1195#[rustc_nounwind]
1196#[cfg(not(feature = "ferrocene_subset"))]
1197pub fn powf64(a: f64, x: f64) -> f64;
1198/// Raises an `f128` to an `f128` power.
1199///
1200/// The stabilized version of this intrinsic is
1201/// [`f128::powf`](../../std/primitive.f128.html#method.powf)
1202#[rustc_intrinsic]
1203#[rustc_nounwind]
1204#[cfg(not(feature = "ferrocene_subset"))]
1205pub fn powf128(a: f128, x: f128) -> f128;
1206
1207/// Returns the exponential of an `f16`.
1208///
1209/// The stabilized version of this intrinsic is
1210/// [`f16::exp`](../../std/primitive.f16.html#method.exp)
1211#[rustc_intrinsic]
1212#[rustc_nounwind]
1213#[cfg(not(feature = "ferrocene_subset"))]
1214pub fn expf16(x: f16) -> f16;
1215/// Returns the exponential of an `f32`.
1216///
1217/// The stabilized version of this intrinsic is
1218/// [`f32::exp`](../../std/primitive.f32.html#method.exp)
1219#[rustc_intrinsic]
1220#[rustc_nounwind]
1221#[cfg(not(feature = "ferrocene_subset"))]
1222pub fn expf32(x: f32) -> f32;
1223/// Returns the exponential of an `f64`.
1224///
1225/// The stabilized version of this intrinsic is
1226/// [`f64::exp`](../../std/primitive.f64.html#method.exp)
1227#[rustc_intrinsic]
1228#[rustc_nounwind]
1229#[cfg(not(feature = "ferrocene_subset"))]
1230pub fn expf64(x: f64) -> f64;
1231/// Returns the exponential of an `f128`.
1232///
1233/// The stabilized version of this intrinsic is
1234/// [`f128::exp`](../../std/primitive.f128.html#method.exp)
1235#[rustc_intrinsic]
1236#[rustc_nounwind]
1237#[cfg(not(feature = "ferrocene_subset"))]
1238pub fn expf128(x: f128) -> f128;
1239
1240/// Returns 2 raised to the power of an `f16`.
1241///
1242/// The stabilized version of this intrinsic is
1243/// [`f16::exp2`](../../std/primitive.f16.html#method.exp2)
1244#[rustc_intrinsic]
1245#[rustc_nounwind]
1246#[cfg(not(feature = "ferrocene_subset"))]
1247pub fn exp2f16(x: f16) -> f16;
1248/// Returns 2 raised to the power of an `f32`.
1249///
1250/// The stabilized version of this intrinsic is
1251/// [`f32::exp2`](../../std/primitive.f32.html#method.exp2)
1252#[rustc_intrinsic]
1253#[rustc_nounwind]
1254#[cfg(not(feature = "ferrocene_subset"))]
1255pub fn exp2f32(x: f32) -> f32;
1256/// Returns 2 raised to the power of an `f64`.
1257///
1258/// The stabilized version of this intrinsic is
1259/// [`f64::exp2`](../../std/primitive.f64.html#method.exp2)
1260#[rustc_intrinsic]
1261#[rustc_nounwind]
1262#[cfg(not(feature = "ferrocene_subset"))]
1263pub fn exp2f64(x: f64) -> f64;
1264/// Returns 2 raised to the power of an `f128`.
1265///
1266/// The stabilized version of this intrinsic is
1267/// [`f128::exp2`](../../std/primitive.f128.html#method.exp2)
1268#[rustc_intrinsic]
1269#[rustc_nounwind]
1270#[cfg(not(feature = "ferrocene_subset"))]
1271pub fn exp2f128(x: f128) -> f128;
1272
1273/// Returns the natural logarithm of an `f16`.
1274///
1275/// The stabilized version of this intrinsic is
1276/// [`f16::ln`](../../std/primitive.f16.html#method.ln)
1277#[rustc_intrinsic]
1278#[rustc_nounwind]
1279#[cfg(not(feature = "ferrocene_subset"))]
1280pub fn logf16(x: f16) -> f16;
1281/// Returns the natural logarithm of an `f32`.
1282///
1283/// The stabilized version of this intrinsic is
1284/// [`f32::ln`](../../std/primitive.f32.html#method.ln)
1285#[rustc_intrinsic]
1286#[rustc_nounwind]
1287#[cfg(not(feature = "ferrocene_subset"))]
1288pub fn logf32(x: f32) -> f32;
1289/// Returns the natural logarithm of an `f64`.
1290///
1291/// The stabilized version of this intrinsic is
1292/// [`f64::ln`](../../std/primitive.f64.html#method.ln)
1293#[rustc_intrinsic]
1294#[rustc_nounwind]
1295#[cfg(not(feature = "ferrocene_subset"))]
1296pub fn logf64(x: f64) -> f64;
1297/// Returns the natural logarithm of an `f128`.
1298///
1299/// The stabilized version of this intrinsic is
1300/// [`f128::ln`](../../std/primitive.f128.html#method.ln)
1301#[rustc_intrinsic]
1302#[rustc_nounwind]
1303#[cfg(not(feature = "ferrocene_subset"))]
1304pub fn logf128(x: f128) -> f128;
1305
1306/// Returns the base 10 logarithm of an `f16`.
1307///
1308/// The stabilized version of this intrinsic is
1309/// [`f16::log10`](../../std/primitive.f16.html#method.log10)
1310#[rustc_intrinsic]
1311#[rustc_nounwind]
1312#[cfg(not(feature = "ferrocene_subset"))]
1313pub fn log10f16(x: f16) -> f16;
1314/// Returns the base 10 logarithm of an `f32`.
1315///
1316/// The stabilized version of this intrinsic is
1317/// [`f32::log10`](../../std/primitive.f32.html#method.log10)
1318#[rustc_intrinsic]
1319#[rustc_nounwind]
1320#[cfg(not(feature = "ferrocene_subset"))]
1321pub fn log10f32(x: f32) -> f32;
1322/// Returns the base 10 logarithm of an `f64`.
1323///
1324/// The stabilized version of this intrinsic is
1325/// [`f64::log10`](../../std/primitive.f64.html#method.log10)
1326#[rustc_intrinsic]
1327#[rustc_nounwind]
1328#[cfg(not(feature = "ferrocene_subset"))]
1329pub fn log10f64(x: f64) -> f64;
1330/// Returns the base 10 logarithm of an `f128`.
1331///
1332/// The stabilized version of this intrinsic is
1333/// [`f128::log10`](../../std/primitive.f128.html#method.log10)
1334#[rustc_intrinsic]
1335#[rustc_nounwind]
1336#[cfg(not(feature = "ferrocene_subset"))]
1337pub fn log10f128(x: f128) -> f128;
1338
1339/// Returns the base 2 logarithm of an `f16`.
1340///
1341/// The stabilized version of this intrinsic is
1342/// [`f16::log2`](../../std/primitive.f16.html#method.log2)
1343#[rustc_intrinsic]
1344#[rustc_nounwind]
1345#[cfg(not(feature = "ferrocene_subset"))]
1346pub fn log2f16(x: f16) -> f16;
1347/// Returns the base 2 logarithm of an `f32`.
1348///
1349/// The stabilized version of this intrinsic is
1350/// [`f32::log2`](../../std/primitive.f32.html#method.log2)
1351#[rustc_intrinsic]
1352#[rustc_nounwind]
1353#[cfg(not(feature = "ferrocene_subset"))]
1354pub fn log2f32(x: f32) -> f32;
1355/// Returns the base 2 logarithm of an `f64`.
1356///
1357/// The stabilized version of this intrinsic is
1358/// [`f64::log2`](../../std/primitive.f64.html#method.log2)
1359#[rustc_intrinsic]
1360#[rustc_nounwind]
1361#[cfg(not(feature = "ferrocene_subset"))]
1362pub fn log2f64(x: f64) -> f64;
1363/// Returns the base 2 logarithm of an `f128`.
1364///
1365/// The stabilized version of this intrinsic is
1366/// [`f128::log2`](../../std/primitive.f128.html#method.log2)
1367#[rustc_intrinsic]
1368#[rustc_nounwind]
1369#[cfg(not(feature = "ferrocene_subset"))]
1370pub fn log2f128(x: f128) -> f128;
1371
1372/// Returns `a * b + c` for `f16` values.
1373///
1374/// The stabilized version of this intrinsic is
1375/// [`f16::mul_add`](../../std/primitive.f16.html#method.mul_add)
1376#[rustc_intrinsic_const_stable_indirect]
1377#[rustc_intrinsic]
1378#[rustc_nounwind]
1379pub const fn fmaf16(a: f16, b: f16, c: f16) -> f16;
1380/// Returns `a * b + c` for `f32` values.
1381///
1382/// The stabilized version of this intrinsic is
1383/// [`f32::mul_add`](../../std/primitive.f32.html#method.mul_add)
1384#[rustc_intrinsic_const_stable_indirect]
1385#[rustc_intrinsic]
1386#[rustc_nounwind]
1387pub const fn fmaf32(a: f32, b: f32, c: f32) -> f32;
1388/// Returns `a * b + c` for `f64` values.
1389///
1390/// The stabilized version of this intrinsic is
1391/// [`f64::mul_add`](../../std/primitive.f64.html#method.mul_add)
1392#[rustc_intrinsic_const_stable_indirect]
1393#[rustc_intrinsic]
1394#[rustc_nounwind]
1395pub const fn fmaf64(a: f64, b: f64, c: f64) -> f64;
1396/// Returns `a * b + c` for `f128` values.
1397///
1398/// The stabilized version of this intrinsic is
1399/// [`f128::mul_add`](../../std/primitive.f128.html#method.mul_add)
1400#[rustc_intrinsic_const_stable_indirect]
1401#[rustc_intrinsic]
1402#[rustc_nounwind]
1403#[cfg(not(feature = "ferrocene_subset"))]
1404pub const fn fmaf128(a: f128, b: f128, c: f128) -> f128;
1405
1406/// Returns `a * b + c` for `f16` values, non-deterministically executing
1407/// either a fused multiply-add or two operations with rounding of the
1408/// intermediate result.
1409///
1410/// The operation is fused if the code generator determines that target
1411/// instruction set has support for a fused operation, and that the fused
1412/// operation is more efficient than the equivalent, separate pair of mul
1413/// and add instructions. It is unspecified whether or not a fused operation
1414/// is selected, and that may depend on optimization level and context, for
1415/// example.
1416#[rustc_intrinsic]
1417#[rustc_nounwind]
1418#[cfg(not(feature = "ferrocene_subset"))]
1419pub const fn fmuladdf16(a: f16, b: f16, c: f16) -> f16;
1420/// Returns `a * b + c` for `f32` values, non-deterministically executing
1421/// either a fused multiply-add or two operations with rounding of the
1422/// intermediate result.
1423///
1424/// The operation is fused if the code generator determines that target
1425/// instruction set has support for a fused operation, and that the fused
1426/// operation is more efficient than the equivalent, separate pair of mul
1427/// and add instructions. It is unspecified whether or not a fused operation
1428/// is selected, and that may depend on optimization level and context, for
1429/// example.
1430#[rustc_intrinsic]
1431#[rustc_nounwind]
1432#[cfg(not(feature = "ferrocene_subset"))]
1433pub const fn fmuladdf32(a: f32, b: f32, c: f32) -> f32;
1434/// Returns `a * b + c` for `f64` values, non-deterministically executing
1435/// either a fused multiply-add or two operations with rounding of the
1436/// intermediate result.
1437///
1438/// The operation is fused if the code generator determines that target
1439/// instruction set has support for a fused operation, and that the fused
1440/// operation is more efficient than the equivalent, separate pair of mul
1441/// and add instructions. It is unspecified whether or not a fused operation
1442/// is selected, and that may depend on optimization level and context, for
1443/// example.
1444#[rustc_intrinsic]
1445#[rustc_nounwind]
1446#[cfg(not(feature = "ferrocene_subset"))]
1447pub const fn fmuladdf64(a: f64, b: f64, c: f64) -> f64;
1448/// Returns `a * b + c` for `f128` values, non-deterministically executing
1449/// either a fused multiply-add or two operations with rounding of the
1450/// intermediate result.
1451///
1452/// The operation is fused if the code generator determines that target
1453/// instruction set has support for a fused operation, and that the fused
1454/// operation is more efficient than the equivalent, separate pair of mul
1455/// and add instructions. It is unspecified whether or not a fused operation
1456/// is selected, and that may depend on optimization level and context, for
1457/// example.
1458#[rustc_intrinsic]
1459#[rustc_nounwind]
1460#[cfg(not(feature = "ferrocene_subset"))]
1461pub const fn fmuladdf128(a: f128, b: f128, c: f128) -> f128;
1462
1463/// Returns the largest integer less than or equal to an `f16`.
1464///
1465/// The stabilized version of this intrinsic is
1466/// [`f16::floor`](../../std/primitive.f16.html#method.floor)
1467#[rustc_intrinsic_const_stable_indirect]
1468#[rustc_intrinsic]
1469#[rustc_nounwind]
1470#[cfg(not(feature = "ferrocene_subset"))]
1471pub const fn floorf16(x: f16) -> f16;
1472/// Returns the largest integer less than or equal to an `f32`.
1473///
1474/// The stabilized version of this intrinsic is
1475/// [`f32::floor`](../../std/primitive.f32.html#method.floor)
1476#[rustc_intrinsic_const_stable_indirect]
1477#[rustc_intrinsic]
1478#[rustc_nounwind]
1479#[cfg(not(feature = "ferrocene_subset"))]
1480pub const fn floorf32(x: f32) -> f32;
1481/// Returns the largest integer less than or equal to an `f64`.
1482///
1483/// The stabilized version of this intrinsic is
1484/// [`f64::floor`](../../std/primitive.f64.html#method.floor)
1485#[rustc_intrinsic_const_stable_indirect]
1486#[rustc_intrinsic]
1487#[rustc_nounwind]
1488#[cfg(not(feature = "ferrocene_subset"))]
1489pub const fn floorf64(x: f64) -> f64;
1490/// Returns the largest integer less than or equal to an `f128`.
1491///
1492/// The stabilized version of this intrinsic is
1493/// [`f128::floor`](../../std/primitive.f128.html#method.floor)
1494#[rustc_intrinsic_const_stable_indirect]
1495#[rustc_intrinsic]
1496#[rustc_nounwind]
1497#[cfg(not(feature = "ferrocene_subset"))]
1498pub const fn floorf128(x: f128) -> f128;
1499
1500/// Returns the smallest integer greater than or equal to an `f16`.
1501///
1502/// The stabilized version of this intrinsic is
1503/// [`f16::ceil`](../../std/primitive.f16.html#method.ceil)
1504#[rustc_intrinsic_const_stable_indirect]
1505#[rustc_intrinsic]
1506#[rustc_nounwind]
1507#[cfg(not(feature = "ferrocene_subset"))]
1508pub const fn ceilf16(x: f16) -> f16;
1509/// Returns the smallest integer greater than or equal to an `f32`.
1510///
1511/// The stabilized version of this intrinsic is
1512/// [`f32::ceil`](../../std/primitive.f32.html#method.ceil)
1513#[rustc_intrinsic_const_stable_indirect]
1514#[rustc_intrinsic]
1515#[rustc_nounwind]
1516#[cfg(not(feature = "ferrocene_subset"))]
1517pub const fn ceilf32(x: f32) -> f32;
1518/// Returns the smallest integer greater than or equal to an `f64`.
1519///
1520/// The stabilized version of this intrinsic is
1521/// [`f64::ceil`](../../std/primitive.f64.html#method.ceil)
1522#[rustc_intrinsic_const_stable_indirect]
1523#[rustc_intrinsic]
1524#[rustc_nounwind]
1525#[cfg(not(feature = "ferrocene_subset"))]
1526pub const fn ceilf64(x: f64) -> f64;
1527/// Returns the smallest integer greater than or equal to an `f128`.
1528///
1529/// The stabilized version of this intrinsic is
1530/// [`f128::ceil`](../../std/primitive.f128.html#method.ceil)
1531#[rustc_intrinsic_const_stable_indirect]
1532#[rustc_intrinsic]
1533#[rustc_nounwind]
1534#[cfg(not(feature = "ferrocene_subset"))]
1535pub const fn ceilf128(x: f128) -> f128;
1536
1537/// Returns the integer part of an `f16`.
1538///
1539/// The stabilized version of this intrinsic is
1540/// [`f16::trunc`](../../std/primitive.f16.html#method.trunc)
1541#[rustc_intrinsic_const_stable_indirect]
1542#[rustc_intrinsic]
1543#[rustc_nounwind]
1544#[cfg(not(feature = "ferrocene_subset"))]
1545pub const fn truncf16(x: f16) -> f16;
1546/// Returns the integer part of an `f32`.
1547///
1548/// The stabilized version of this intrinsic is
1549/// [`f32::trunc`](../../std/primitive.f32.html#method.trunc)
1550#[rustc_intrinsic_const_stable_indirect]
1551#[rustc_intrinsic]
1552#[rustc_nounwind]
1553#[cfg(not(feature = "ferrocene_subset"))]
1554pub const fn truncf32(x: f32) -> f32;
1555/// Returns the integer part of an `f64`.
1556///
1557/// The stabilized version of this intrinsic is
1558/// [`f64::trunc`](../../std/primitive.f64.html#method.trunc)
1559#[rustc_intrinsic_const_stable_indirect]
1560#[rustc_intrinsic]
1561#[rustc_nounwind]
1562#[cfg(not(feature = "ferrocene_subset"))]
1563pub const fn truncf64(x: f64) -> f64;
1564/// Returns the integer part of an `f128`.
1565///
1566/// The stabilized version of this intrinsic is
1567/// [`f128::trunc`](../../std/primitive.f128.html#method.trunc)
1568#[rustc_intrinsic_const_stable_indirect]
1569#[rustc_intrinsic]
1570#[rustc_nounwind]
1571#[cfg(not(feature = "ferrocene_subset"))]
1572pub const fn truncf128(x: f128) -> f128;
1573
1574/// Returns the nearest integer to an `f16`. Rounds half-way cases to the number with an even
1575/// least significant digit.
1576///
1577/// The stabilized version of this intrinsic is
1578/// [`f16::round_ties_even`](../../std/primitive.f16.html#method.round_ties_even)
1579#[rustc_intrinsic_const_stable_indirect]
1580#[rustc_intrinsic]
1581#[rustc_nounwind]
1582#[cfg(not(feature = "ferrocene_subset"))]
1583pub const fn round_ties_even_f16(x: f16) -> f16;
1584
1585/// Returns the nearest integer to an `f32`. Rounds half-way cases to the number with an even
1586/// least significant digit.
1587///
1588/// The stabilized version of this intrinsic is
1589/// [`f32::round_ties_even`](../../std/primitive.f32.html#method.round_ties_even)
1590#[rustc_intrinsic_const_stable_indirect]
1591#[rustc_intrinsic]
1592#[rustc_nounwind]
1593#[cfg(not(feature = "ferrocene_subset"))]
1594pub const fn round_ties_even_f32(x: f32) -> f32;
1595
1596/// Returns the nearest integer to an `f64`. Rounds half-way cases to the number with an even
1597/// least significant digit.
1598///
1599/// The stabilized version of this intrinsic is
1600/// [`f64::round_ties_even`](../../std/primitive.f64.html#method.round_ties_even)
1601#[rustc_intrinsic_const_stable_indirect]
1602#[rustc_intrinsic]
1603#[rustc_nounwind]
1604#[cfg(not(feature = "ferrocene_subset"))]
1605pub const fn round_ties_even_f64(x: f64) -> f64;
1606
1607/// Returns the nearest integer to an `f128`. Rounds half-way cases to the number with an even
1608/// least significant digit.
1609///
1610/// The stabilized version of this intrinsic is
1611/// [`f128::round_ties_even`](../../std/primitive.f128.html#method.round_ties_even)
1612#[rustc_intrinsic_const_stable_indirect]
1613#[rustc_intrinsic]
1614#[rustc_nounwind]
1615#[cfg(not(feature = "ferrocene_subset"))]
1616pub const fn round_ties_even_f128(x: f128) -> f128;
1617
1618/// Returns the nearest integer to an `f16`. Rounds half-way cases away from zero.
1619///
1620/// The stabilized version of this intrinsic is
1621/// [`f16::round`](../../std/primitive.f16.html#method.round)
1622#[rustc_intrinsic_const_stable_indirect]
1623#[rustc_intrinsic]
1624#[rustc_nounwind]
1625#[cfg(not(feature = "ferrocene_subset"))]
1626pub const fn roundf16(x: f16) -> f16;
1627/// Returns the nearest integer to an `f32`. Rounds half-way cases away from zero.
1628///
1629/// The stabilized version of this intrinsic is
1630/// [`f32::round`](../../std/primitive.f32.html#method.round)
1631#[rustc_intrinsic_const_stable_indirect]
1632#[rustc_intrinsic]
1633#[rustc_nounwind]
1634#[cfg(not(feature = "ferrocene_subset"))]
1635pub const fn roundf32(x: f32) -> f32;
1636/// Returns the nearest integer to an `f64`. Rounds half-way cases away from zero.
1637///
1638/// The stabilized version of this intrinsic is
1639/// [`f64::round`](../../std/primitive.f64.html#method.round)
1640#[rustc_intrinsic_const_stable_indirect]
1641#[rustc_intrinsic]
1642#[rustc_nounwind]
1643#[cfg(not(feature = "ferrocene_subset"))]
1644pub const fn roundf64(x: f64) -> f64;
1645/// Returns the nearest integer to an `f128`. Rounds half-way cases away from zero.
1646///
1647/// The stabilized version of this intrinsic is
1648/// [`f128::round`](../../std/primitive.f128.html#method.round)
1649#[rustc_intrinsic_const_stable_indirect]
1650#[rustc_intrinsic]
1651#[rustc_nounwind]
1652#[cfg(not(feature = "ferrocene_subset"))]
1653pub const fn roundf128(x: f128) -> f128;
1654
1655/// Float addition that allows optimizations based on algebraic rules.
1656/// Requires that inputs and output of the operation are finite, causing UB otherwise.
1657///
1658/// This intrinsic does not have a stable counterpart.
1659#[rustc_intrinsic]
1660#[rustc_nounwind]
1661#[cfg(not(feature = "ferrocene_subset"))]
1662pub unsafe fn fadd_fast<T: Copy>(a: T, b: T) -> T;
1663
1664/// Float subtraction that allows optimizations based on algebraic rules.
1665/// Requires that inputs and output of the operation are finite, causing UB otherwise.
1666///
1667/// This intrinsic does not have a stable counterpart.
1668#[rustc_intrinsic]
1669#[rustc_nounwind]
1670#[cfg(not(feature = "ferrocene_subset"))]
1671pub unsafe fn fsub_fast<T: Copy>(a: T, b: T) -> T;
1672
1673/// Float multiplication that allows optimizations based on algebraic rules.
1674/// Requires that inputs and output of the operation are finite, causing UB otherwise.
1675///
1676/// This intrinsic does not have a stable counterpart.
1677#[rustc_intrinsic]
1678#[rustc_nounwind]
1679#[cfg(not(feature = "ferrocene_subset"))]
1680pub unsafe fn fmul_fast<T: Copy>(a: T, b: T) -> T;
1681
1682/// Float division that allows optimizations based on algebraic rules.
1683/// Requires that inputs and output of the operation are finite, causing UB otherwise.
1684///
1685/// This intrinsic does not have a stable counterpart.
1686#[rustc_intrinsic]
1687#[rustc_nounwind]
1688#[cfg(not(feature = "ferrocene_subset"))]
1689pub unsafe fn fdiv_fast<T: Copy>(a: T, b: T) -> T;
1690
1691/// Float remainder that allows optimizations based on algebraic rules.
1692/// Requires that inputs and output of the operation are finite, causing UB otherwise.
1693///
1694/// This intrinsic does not have a stable counterpart.
1695#[rustc_intrinsic]
1696#[rustc_nounwind]
1697#[cfg(not(feature = "ferrocene_subset"))]
1698pub unsafe fn frem_fast<T: Copy>(a: T, b: T) -> T;
1699
1700/// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range
1701/// (<https://github.com/rust-lang/rust/issues/10184>)
1702///
1703/// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`].
1704#[rustc_intrinsic]
1705#[rustc_nounwind]
1706#[cfg(not(feature = "ferrocene_subset"))]
1707pub unsafe fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
1708
1709/// Float addition that allows optimizations based on algebraic rules.
1710///
1711/// Stabilized as [`f16::algebraic_add`], [`f32::algebraic_add`], [`f64::algebraic_add`] and [`f128::algebraic_add`].
1712#[rustc_nounwind]
1713#[rustc_intrinsic]
1714#[cfg(not(feature = "ferrocene_subset"))]
1715pub const fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
1716
1717/// Float subtraction that allows optimizations based on algebraic rules.
1718///
1719/// Stabilized as [`f16::algebraic_sub`], [`f32::algebraic_sub`], [`f64::algebraic_sub`] and [`f128::algebraic_sub`].
1720#[rustc_nounwind]
1721#[rustc_intrinsic]
1722#[cfg(not(feature = "ferrocene_subset"))]
1723pub const fn fsub_algebraic<T: Copy>(a: T, b: T) -> T;
1724
1725/// Float multiplication that allows optimizations based on algebraic rules.
1726///
1727/// Stabilized as [`f16::algebraic_mul`], [`f32::algebraic_mul`], [`f64::algebraic_mul`] and [`f128::algebraic_mul`].
1728#[rustc_nounwind]
1729#[rustc_intrinsic]
1730#[cfg(not(feature = "ferrocene_subset"))]
1731pub const fn fmul_algebraic<T: Copy>(a: T, b: T) -> T;
1732
1733/// Float division that allows optimizations based on algebraic rules.
1734///
1735/// Stabilized as [`f16::algebraic_div`], [`f32::algebraic_div`], [`f64::algebraic_div`] and [`f128::algebraic_div`].
1736#[rustc_nounwind]
1737#[rustc_intrinsic]
1738#[cfg(not(feature = "ferrocene_subset"))]
1739pub const fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T;
1740
1741/// Float remainder that allows optimizations based on algebraic rules.
1742///
1743/// Stabilized as [`f16::algebraic_rem`], [`f32::algebraic_rem`], [`f64::algebraic_rem`] and [`f128::algebraic_rem`].
1744#[rustc_nounwind]
1745#[rustc_intrinsic]
1746#[cfg(not(feature = "ferrocene_subset"))]
1747pub const fn frem_algebraic<T: Copy>(a: T, b: T) -> T;
1748
1749/// Returns the number of bits set in an integer type `T`
1750///
1751/// Note that, unlike most intrinsics, this is safe to call;
1752/// it does not require an `unsafe` block.
1753/// Therefore, implementations must not require the user to uphold
1754/// any safety invariants.
1755///
1756/// The stabilized versions of this intrinsic are available on the integer
1757/// primitives via the `count_ones` method. For example,
1758/// [`u32::count_ones`]
1759#[rustc_intrinsic_const_stable_indirect]
1760#[rustc_nounwind]
1761#[rustc_intrinsic]
1762pub const fn ctpop<T: Copy>(x: T) -> u32;
1763
1764/// Returns the number of leading unset bits (zeroes) in an integer type `T`.
1765///
1766/// Note that, unlike most intrinsics, this is safe to call;
1767/// it does not require an `unsafe` block.
1768/// Therefore, implementations must not require the user to uphold
1769/// any safety invariants.
1770///
1771/// The stabilized versions of this intrinsic are available on the integer
1772/// primitives via the `leading_zeros` method. For example,
1773/// [`u32::leading_zeros`]
1774///
1775/// # Examples
1776///
1777/// ```
1778/// #![feature(core_intrinsics)]
1779/// # #![allow(internal_features)]
1780///
1781/// use std::intrinsics::ctlz;
1782///
1783/// let x = 0b0001_1100_u8;
1784/// let num_leading = ctlz(x);
1785/// assert_eq!(num_leading, 3);
1786/// ```
1787///
1788/// An `x` with value `0` will return the bit width of `T`.
1789///
1790/// ```
1791/// #![feature(core_intrinsics)]
1792/// # #![allow(internal_features)]
1793///
1794/// use std::intrinsics::ctlz;
1795///
1796/// let x = 0u16;
1797/// let num_leading = ctlz(x);
1798/// assert_eq!(num_leading, 16);
1799/// ```
1800#[rustc_intrinsic_const_stable_indirect]
1801#[rustc_nounwind]
1802#[rustc_intrinsic]
1803pub const fn ctlz<T: Copy>(x: T) -> u32;
1804
1805/// Like `ctlz`, but extra-unsafe as it returns `undef` when
1806/// given an `x` with value `0`.
1807///
1808/// This intrinsic does not have a stable counterpart.
1809///
1810/// # Examples
1811///
1812/// ```
1813/// #![feature(core_intrinsics)]
1814/// # #![allow(internal_features)]
1815///
1816/// use std::intrinsics::ctlz_nonzero;
1817///
1818/// let x = 0b0001_1100_u8;
1819/// let num_leading = unsafe { ctlz_nonzero(x) };
1820/// assert_eq!(num_leading, 3);
1821/// ```
1822#[rustc_intrinsic_const_stable_indirect]
1823#[rustc_nounwind]
1824#[rustc_intrinsic]
1825pub const unsafe fn ctlz_nonzero<T: Copy>(x: T) -> u32;
1826
1827/// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
1828///
1829/// Note that, unlike most intrinsics, this is safe to call;
1830/// it does not require an `unsafe` block.
1831/// Therefore, implementations must not require the user to uphold
1832/// any safety invariants.
1833///
1834/// The stabilized versions of this intrinsic are available on the integer
1835/// primitives via the `trailing_zeros` method. For example,
1836/// [`u32::trailing_zeros`]
1837///
1838/// # Examples
1839///
1840/// ```
1841/// #![feature(core_intrinsics)]
1842/// # #![allow(internal_features)]
1843///
1844/// use std::intrinsics::cttz;
1845///
1846/// let x = 0b0011_1000_u8;
1847/// let num_trailing = cttz(x);
1848/// assert_eq!(num_trailing, 3);
1849/// ```
1850///
1851/// An `x` with value `0` will return the bit width of `T`:
1852///
1853/// ```
1854/// #![feature(core_intrinsics)]
1855/// # #![allow(internal_features)]
1856///
1857/// use std::intrinsics::cttz;
1858///
1859/// let x = 0u16;
1860/// let num_trailing = cttz(x);
1861/// assert_eq!(num_trailing, 16);
1862/// ```
1863#[rustc_intrinsic_const_stable_indirect]
1864#[rustc_nounwind]
1865#[rustc_intrinsic]
1866pub const fn cttz<T: Copy>(x: T) -> u32;
1867
1868/// Like `cttz`, but extra-unsafe as it returns `undef` when
1869/// given an `x` with value `0`.
1870///
1871/// This intrinsic does not have a stable counterpart.
1872///
1873/// # Examples
1874///
1875/// ```
1876/// #![feature(core_intrinsics)]
1877/// # #![allow(internal_features)]
1878///
1879/// use std::intrinsics::cttz_nonzero;
1880///
1881/// let x = 0b0011_1000_u8;
1882/// let num_trailing = unsafe { cttz_nonzero(x) };
1883/// assert_eq!(num_trailing, 3);
1884/// ```
1885#[rustc_intrinsic_const_stable_indirect]
1886#[rustc_nounwind]
1887#[rustc_intrinsic]
1888pub const unsafe fn cttz_nonzero<T: Copy>(x: T) -> u32;
1889
1890/// Reverses the bytes in an integer type `T`.
1891///
1892/// Note that, unlike most intrinsics, this is safe to call;
1893/// it does not require an `unsafe` block.
1894/// Therefore, implementations must not require the user to uphold
1895/// any safety invariants.
1896///
1897/// The stabilized versions of this intrinsic are available on the integer
1898/// primitives via the `swap_bytes` method. For example,
1899/// [`u32::swap_bytes`]
1900#[rustc_intrinsic_const_stable_indirect]
1901#[rustc_nounwind]
1902#[rustc_intrinsic]
1903pub const fn bswap<T: Copy>(x: T) -> T;
1904
1905/// Reverses the bits in an integer type `T`.
1906///
1907/// Note that, unlike most intrinsics, this is safe to call;
1908/// it does not require an `unsafe` block.
1909/// Therefore, implementations must not require the user to uphold
1910/// any safety invariants.
1911///
1912/// The stabilized versions of this intrinsic are available on the integer
1913/// primitives via the `reverse_bits` method. For example,
1914/// [`u32::reverse_bits`]
1915#[rustc_intrinsic_const_stable_indirect]
1916#[rustc_nounwind]
1917#[rustc_intrinsic]
1918pub const fn bitreverse<T: Copy>(x: T) -> T;
1919
1920/// Does a three-way comparison between the two arguments,
1921/// which must be of character or integer (signed or unsigned) type.
1922///
1923/// This was originally added because it greatly simplified the MIR in `cmp`
1924/// implementations, and then LLVM 20 added a backend intrinsic for it too.
1925///
1926/// The stabilized version of this intrinsic is [`Ord::cmp`].
1927#[rustc_intrinsic_const_stable_indirect]
1928#[rustc_nounwind]
1929#[rustc_intrinsic]
1930pub const fn three_way_compare<T: Copy>(lhs: T, rhss: T) -> crate::cmp::Ordering;
1931
1932/// Combine two values which have no bits in common.
1933///
1934/// This allows the backend to implement it as `a + b` *or* `a | b`,
1935/// depending which is easier to implement on a specific target.
1936///
1937/// # Safety
1938///
1939/// Requires that `(a & b) == 0`, or equivalently that `(a | b) == (a + b)`.
1940///
1941/// Otherwise it's immediate UB.
1942#[rustc_const_unstable(feature = "disjoint_bitor", issue = "135758")]
1943#[rustc_nounwind]
1944#[rustc_intrinsic]
1945#[track_caller]
1946#[miri::intrinsic_fallback_is_spec] // the fallbacks all `assume` to tell Miri
1947#[ferrocene::annotation(
1948    "This function only redirects to `intrinsics::fallback::DisjointBitOr::disjoint_bitor` which is thoroughly tested. The fact this is shown as uncovered is a known problem in our coverage tooling."
1949)]
1950pub const unsafe fn disjoint_bitor<T: [const] fallback::DisjointBitOr>(a: T, b: T) -> T {
1951    // SAFETY: same preconditions as this function.
1952    unsafe { fallback::DisjointBitOr::disjoint_bitor(a, b) }
1953}
1954
1955/// Performs checked integer addition.
1956///
1957/// Note that, unlike most intrinsics, this is safe to call;
1958/// it does not require an `unsafe` block.
1959/// Therefore, implementations must not require the user to uphold
1960/// any safety invariants.
1961///
1962/// The stabilized versions of this intrinsic are available on the integer
1963/// primitives via the `overflowing_add` method. For example,
1964/// [`u32::overflowing_add`]
1965#[rustc_intrinsic_const_stable_indirect]
1966#[rustc_nounwind]
1967#[rustc_intrinsic]
1968pub const fn add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
1969
1970/// Performs checked integer subtraction
1971///
1972/// Note that, unlike most intrinsics, this is safe to call;
1973/// it does not require an `unsafe` block.
1974/// Therefore, implementations must not require the user to uphold
1975/// any safety invariants.
1976///
1977/// The stabilized versions of this intrinsic are available on the integer
1978/// primitives via the `overflowing_sub` method. For example,
1979/// [`u32::overflowing_sub`]
1980#[rustc_intrinsic_const_stable_indirect]
1981#[rustc_nounwind]
1982#[rustc_intrinsic]
1983pub const fn sub_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
1984
1985/// Performs checked integer multiplication
1986///
1987/// Note that, unlike most intrinsics, this is safe to call;
1988/// it does not require an `unsafe` block.
1989/// Therefore, implementations must not require the user to uphold
1990/// any safety invariants.
1991///
1992/// The stabilized versions of this intrinsic are available on the integer
1993/// primitives via the `overflowing_mul` method. For example,
1994/// [`u32::overflowing_mul`]
1995#[rustc_intrinsic_const_stable_indirect]
1996#[rustc_nounwind]
1997#[rustc_intrinsic]
1998pub const fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
1999
2000/// Performs full-width multiplication and addition with a carry:
2001/// `multiplier * multiplicand + addend + carry`.
2002///
2003/// This is possible without any overflow.  For `uN`:
2004///    MAX * MAX + MAX + MAX
2005/// => (2ⁿ-1) × (2ⁿ-1) + (2ⁿ-1) + (2ⁿ-1)
2006/// => (2²ⁿ - 2ⁿ⁺¹ + 1) + (2ⁿ⁺¹ - 2)
2007/// => 2²ⁿ - 1
2008///
2009/// For `iN`, the upper bound is MIN * MIN + MAX + MAX => 2²ⁿ⁻² + 2ⁿ - 2,
2010/// and the lower bound is MAX * MIN + MIN + MIN => -2²ⁿ⁻² - 2ⁿ + 2ⁿ⁺¹.
2011///
2012/// This currently supports unsigned integers *only*, no signed ones.
2013/// The stabilized versions of this intrinsic are available on integers.
2014#[unstable(feature = "core_intrinsics", issue = "none")]
2015#[rustc_const_unstable(feature = "const_carrying_mul_add", issue = "85532")]
2016#[rustc_nounwind]
2017#[rustc_intrinsic]
2018#[miri::intrinsic_fallback_is_spec]
2019pub const fn carrying_mul_add<T: [const] fallback::CarryingMulAdd<Unsigned = U>, U>(
2020    multiplier: T,
2021    multiplicand: T,
2022    addend: T,
2023    carry: T,
2024) -> (U, T) {
2025    multiplier.carrying_mul_add(multiplicand, addend, carry)
2026}
2027
2028/// Performs an exact division, resulting in undefined behavior where
2029/// `x % y != 0` or `y == 0` or `x == T::MIN && y == -1`
2030///
2031/// This intrinsic does not have a stable counterpart.
2032#[rustc_intrinsic_const_stable_indirect]
2033#[rustc_nounwind]
2034#[rustc_intrinsic]
2035pub const unsafe fn exact_div<T: Copy>(x: T, y: T) -> T;
2036
2037/// Performs an unchecked division, resulting in undefined behavior
2038/// where `y == 0` or `x == T::MIN && y == -1`
2039///
2040/// Safe wrappers for this intrinsic are available on the integer
2041/// primitives via the `checked_div` method. For example,
2042/// [`u32::checked_div`]
2043#[rustc_intrinsic_const_stable_indirect]
2044#[rustc_nounwind]
2045#[rustc_intrinsic]
2046pub const unsafe fn unchecked_div<T: Copy>(x: T, y: T) -> T;
2047/// Returns the remainder of an unchecked division, resulting in
2048/// undefined behavior when `y == 0` or `x == T::MIN && y == -1`
2049///
2050/// Safe wrappers for this intrinsic are available on the integer
2051/// primitives via the `checked_rem` method. For example,
2052/// [`u32::checked_rem`]
2053#[rustc_intrinsic_const_stable_indirect]
2054#[rustc_nounwind]
2055#[rustc_intrinsic]
2056pub const unsafe fn unchecked_rem<T: Copy>(x: T, y: T) -> T;
2057
2058/// Performs an unchecked left shift, resulting in undefined behavior when
2059/// `y < 0` or `y >= N`, where N is the width of T in bits.
2060///
2061/// Safe wrappers for this intrinsic are available on the integer
2062/// primitives via the `checked_shl` method. For example,
2063/// [`u32::checked_shl`]
2064#[rustc_intrinsic_const_stable_indirect]
2065#[rustc_nounwind]
2066#[rustc_intrinsic]
2067pub const unsafe fn unchecked_shl<T: Copy, U: Copy>(x: T, y: U) -> T;
2068/// Performs an unchecked right shift, resulting in undefined behavior when
2069/// `y < 0` or `y >= N`, where N is the width of T in bits.
2070///
2071/// Safe wrappers for this intrinsic are available on the integer
2072/// primitives via the `checked_shr` method. For example,
2073/// [`u32::checked_shr`]
2074#[rustc_intrinsic_const_stable_indirect]
2075#[rustc_nounwind]
2076#[rustc_intrinsic]
2077pub const unsafe fn unchecked_shr<T: Copy, U: Copy>(x: T, y: U) -> T;
2078
2079/// Returns the result of an unchecked addition, resulting in
2080/// undefined behavior when `x + y > T::MAX` or `x + y < T::MIN`.
2081///
2082/// The stable counterpart of this intrinsic is `unchecked_add` on the various
2083/// integer types, such as [`u16::unchecked_add`] and [`i64::unchecked_add`].
2084#[rustc_intrinsic_const_stable_indirect]
2085#[rustc_nounwind]
2086#[rustc_intrinsic]
2087pub const unsafe fn unchecked_add<T: Copy>(x: T, y: T) -> T;
2088
2089/// Returns the result of an unchecked subtraction, resulting in
2090/// undefined behavior when `x - y > T::MAX` or `x - y < T::MIN`.
2091///
2092/// The stable counterpart of this intrinsic is `unchecked_sub` on the various
2093/// integer types, such as [`u16::unchecked_sub`] and [`i64::unchecked_sub`].
2094#[rustc_intrinsic_const_stable_indirect]
2095#[rustc_nounwind]
2096#[rustc_intrinsic]
2097pub const unsafe fn unchecked_sub<T: Copy>(x: T, y: T) -> T;
2098
2099/// Returns the result of an unchecked multiplication, resulting in
2100/// undefined behavior when `x * y > T::MAX` or `x * y < T::MIN`.
2101///
2102/// The stable counterpart of this intrinsic is `unchecked_mul` on the various
2103/// integer types, such as [`u16::unchecked_mul`] and [`i64::unchecked_mul`].
2104#[rustc_intrinsic_const_stable_indirect]
2105#[rustc_nounwind]
2106#[rustc_intrinsic]
2107pub const unsafe fn unchecked_mul<T: Copy>(x: T, y: T) -> T;
2108
2109/// Performs rotate left.
2110///
2111/// Note that, unlike most intrinsics, this is safe to call;
2112/// it does not require an `unsafe` block.
2113/// Therefore, implementations must not require the user to uphold
2114/// any safety invariants.
2115///
2116/// The stabilized versions of this intrinsic are available on the integer
2117/// primitives via the `rotate_left` method. For example,
2118/// [`u32::rotate_left`]
2119#[rustc_intrinsic_const_stable_indirect]
2120#[rustc_nounwind]
2121#[rustc_intrinsic]
2122#[rustc_allow_const_fn_unstable(const_trait_impl, funnel_shifts)]
2123#[miri::intrinsic_fallback_is_spec]
2124pub const fn rotate_left<T: [const] fallback::FunnelShift>(x: T, shift: u32) -> T {
2125    // Make sure to call the intrinsic for `funnel_shl`, not the fallback impl.
2126    // SAFETY: we modulo `shift` so that the result is definitely less than the size of
2127    // `T` in bits.
2128    unsafe { unchecked_funnel_shl(x, x, shift % (mem::size_of::<T>() as u32 * 8)) }
2129}
2130
2131/// Performs rotate right.
2132///
2133/// Note that, unlike most intrinsics, this is safe to call;
2134/// it does not require an `unsafe` block.
2135/// Therefore, implementations must not require the user to uphold
2136/// any safety invariants.
2137///
2138/// The stabilized versions of this intrinsic are available on the integer
2139/// primitives via the `rotate_right` method. For example,
2140/// [`u32::rotate_right`]
2141#[rustc_intrinsic_const_stable_indirect]
2142#[rustc_nounwind]
2143#[rustc_intrinsic]
2144#[rustc_allow_const_fn_unstable(const_trait_impl, funnel_shifts)]
2145#[miri::intrinsic_fallback_is_spec]
2146pub const fn rotate_right<T: [const] fallback::FunnelShift>(x: T, shift: u32) -> T {
2147    // Make sure to call the intrinsic for `funnel_shr`, not the fallback impl.
2148    // SAFETY: we modulo `shift` so that the result is definitely less than the size of
2149    // `T` in bits.
2150    unsafe { unchecked_funnel_shr(x, x, shift % (mem::size_of::<T>() as u32 * 8)) }
2151}
2152
2153/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
2154///
2155/// Note that, unlike most intrinsics, this is safe to call;
2156/// it does not require an `unsafe` block.
2157/// Therefore, implementations must not require the user to uphold
2158/// any safety invariants.
2159///
2160/// The stabilized versions of this intrinsic are available on the integer
2161/// primitives via the `wrapping_add` method. For example,
2162/// [`u32::wrapping_add`]
2163#[rustc_intrinsic_const_stable_indirect]
2164#[rustc_nounwind]
2165#[rustc_intrinsic]
2166pub const fn wrapping_add<T: Copy>(a: T, b: T) -> T;
2167/// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
2168///
2169/// Note that, unlike most intrinsics, this is safe to call;
2170/// it does not require an `unsafe` block.
2171/// Therefore, implementations must not require the user to uphold
2172/// any safety invariants.
2173///
2174/// The stabilized versions of this intrinsic are available on the integer
2175/// primitives via the `wrapping_sub` method. For example,
2176/// [`u32::wrapping_sub`]
2177#[rustc_intrinsic_const_stable_indirect]
2178#[rustc_nounwind]
2179#[rustc_intrinsic]
2180pub const fn wrapping_sub<T: Copy>(a: T, b: T) -> T;
2181/// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
2182///
2183/// Note that, unlike most intrinsics, this is safe to call;
2184/// it does not require an `unsafe` block.
2185/// Therefore, implementations must not require the user to uphold
2186/// any safety invariants.
2187///
2188/// The stabilized versions of this intrinsic are available on the integer
2189/// primitives via the `wrapping_mul` method. For example,
2190/// [`u32::wrapping_mul`]
2191#[rustc_intrinsic_const_stable_indirect]
2192#[rustc_nounwind]
2193#[rustc_intrinsic]
2194pub const fn wrapping_mul<T: Copy>(a: T, b: T) -> T;
2195
2196/// Computes `a + b`, saturating at numeric bounds.
2197///
2198/// Note that, unlike most intrinsics, this is safe to call;
2199/// it does not require an `unsafe` block.
2200/// Therefore, implementations must not require the user to uphold
2201/// any safety invariants.
2202///
2203/// The stabilized versions of this intrinsic are available on the integer
2204/// primitives via the `saturating_add` method. For example,
2205/// [`u32::saturating_add`]
2206#[rustc_intrinsic_const_stable_indirect]
2207#[rustc_nounwind]
2208#[rustc_intrinsic]
2209pub const fn saturating_add<T: Copy>(a: T, b: T) -> T;
2210/// Computes `a - b`, saturating at numeric bounds.
2211///
2212/// Note that, unlike most intrinsics, this is safe to call;
2213/// it does not require an `unsafe` block.
2214/// Therefore, implementations must not require the user to uphold
2215/// any safety invariants.
2216///
2217/// The stabilized versions of this intrinsic are available on the integer
2218/// primitives via the `saturating_sub` method. For example,
2219/// [`u32::saturating_sub`]
2220#[rustc_intrinsic_const_stable_indirect]
2221#[rustc_nounwind]
2222#[rustc_intrinsic]
2223pub const fn saturating_sub<T: Copy>(a: T, b: T) -> T;
2224
2225/// Funnel Shift left.
2226///
2227/// Concatenates `a` and `b` (with `a` in the most significant half),
2228/// creating an integer twice as wide. Then shift this integer left
2229/// by `shift`), and extract the most significant half. If `a` and `b`
2230/// are the same, this is equivalent to a rotate left operation.
2231///
2232/// It is undefined behavior if `shift` is greater than or equal to the
2233/// bit size of `T`.
2234///
2235/// Safe versions of this intrinsic are available on the integer primitives
2236/// via the `funnel_shl` method. For example, [`u32::funnel_shl`].
2237#[rustc_intrinsic]
2238#[rustc_nounwind]
2239#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
2240#[unstable(feature = "funnel_shifts", issue = "145686")]
2241#[track_caller]
2242#[miri::intrinsic_fallback_is_spec]
2243#[ferrocene::annotation(
2244    "This function only redirects to `intrinsics::fallback::FunnelShift::unchecked_funnel_shl` which is thoroughly tested. The fact this is shown as uncovered is a known problem in our coverage tooling."
2245)]
2246pub const unsafe fn unchecked_funnel_shl<T: [const] fallback::FunnelShift>(
2247    a: T,
2248    b: T,
2249    shift: u32,
2250) -> T {
2251    // SAFETY: caller ensures that `shift` is in-range
2252    unsafe { a.unchecked_funnel_shl(b, shift) }
2253}
2254
2255/// Funnel Shift right.
2256///
2257/// Concatenates `a` and `b` (with `a` in the most significant half),
2258/// creating an integer twice as wide. Then shift this integer right
2259/// by `shift` (taken modulo the bit size of `T`), and extract the
2260/// least significant half. If `a` and `b` are the same, this is equivalent
2261/// to a rotate right operation.
2262///
2263/// It is undefined behavior if `shift` is greater than or equal to the
2264/// bit size of `T`.
2265///
2266/// Safer versions of this intrinsic are available on the integer primitives
2267/// via the `funnel_shr` method. For example, [`u32::funnel_shr`]
2268#[rustc_intrinsic]
2269#[rustc_nounwind]
2270#[rustc_const_unstable(feature = "funnel_shifts", issue = "145686")]
2271#[unstable(feature = "funnel_shifts", issue = "145686")]
2272#[track_caller]
2273#[miri::intrinsic_fallback_is_spec]
2274#[ferrocene::annotation(
2275    "This function only redirects to `intrinsics::fallback::FunnelShift::unchecked_funnel_shr` which is thoroughly tested. The fact this is shown as uncovered is a known problem in our coverage tooling."
2276)]
2277pub const unsafe fn unchecked_funnel_shr<T: [const] fallback::FunnelShift>(
2278    a: T,
2279    b: T,
2280    shift: u32,
2281) -> T {
2282    // SAFETY: caller ensures that `shift` is in-range
2283    unsafe { a.unchecked_funnel_shr(b, shift) }
2284}
2285
2286/// Carryless multiply.
2287///
2288/// Safe versions of this intrinsic are available on the integer primitives
2289/// via the `carryless_mul` method. For example, [`u32::carryless_mul`].
2290#[rustc_intrinsic]
2291#[rustc_nounwind]
2292#[rustc_const_unstable(feature = "uint_carryless_mul", issue = "152080")]
2293#[unstable(feature = "uint_carryless_mul", issue = "152080")]
2294#[miri::intrinsic_fallback_is_spec]
2295pub const fn carryless_mul<T: [const] fallback::CarrylessMul>(a: T, b: T) -> T {
2296    a.carryless_mul(b)
2297}
2298
2299/// This is an implementation detail of [`crate::ptr::read`] and should
2300/// not be used anywhere else.  See its comments for why this exists.
2301///
2302/// This intrinsic can *only* be called where the pointer is a local without
2303/// projections (`read_via_copy(ptr)`, not `read_via_copy(*ptr)`) so that it
2304/// trivially obeys runtime-MIR rules about derefs in operands.
2305#[rustc_intrinsic_const_stable_indirect]
2306#[rustc_nounwind]
2307#[rustc_intrinsic]
2308pub const unsafe fn read_via_copy<T>(ptr: *const T) -> T;
2309
2310/// This is an implementation detail of [`crate::ptr::write`] and should
2311/// not be used anywhere else.  See its comments for why this exists.
2312///
2313/// This intrinsic can *only* be called where the pointer is a local without
2314/// projections (`write_via_move(ptr, x)`, not `write_via_move(*ptr, x)`) so
2315/// that it trivially obeys runtime-MIR rules about derefs in operands.
2316#[rustc_intrinsic_const_stable_indirect]
2317#[rustc_nounwind]
2318#[rustc_intrinsic]
2319pub const unsafe fn write_via_move<T>(ptr: *mut T, value: T);
2320
2321/// Returns the value of the discriminant for the variant in 'v';
2322/// if `T` has no discriminant, returns `0`.
2323///
2324/// Note that, unlike most intrinsics, this is safe to call;
2325/// it does not require an `unsafe` block.
2326/// Therefore, implementations must not require the user to uphold
2327/// any safety invariants.
2328///
2329/// The stabilized version of this intrinsic is [`core::mem::discriminant`].
2330#[rustc_intrinsic_const_stable_indirect]
2331#[rustc_nounwind]
2332#[rustc_intrinsic]
2333pub const fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
2334
2335/// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the
2336/// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs.
2337/// Returns `1` if unwinding occurred and `catch_fn` was called; returns `0` otherwise.
2338///
2339/// `catch_fn` must not unwind.
2340///
2341/// The third argument is a function called if an unwind occurs (both Rust `panic` and foreign
2342/// unwinds). This function takes the data pointer and a pointer to the target- and
2343/// runtime-specific exception object that was caught.
2344///
2345/// Note that in the case of a foreign unwinding operation, the exception object data may not be
2346/// safely usable from Rust, and should not be directly exposed via the standard library. To
2347/// prevent unsafe access, the library implementation may either abort the process or present an
2348/// opaque error type to the user.
2349///
2350/// For more information, see the compiler's source, as well as the documentation for the stable
2351/// version of this intrinsic, `std::panic::catch_unwind`.
2352#[rustc_intrinsic]
2353#[rustc_nounwind]
2354#[cfg(not(feature = "ferrocene_subset"))]
2355pub unsafe fn catch_unwind(
2356    _try_fn: fn(*mut u8),
2357    _data: *mut u8,
2358    _catch_fn: fn(*mut u8, *mut u8),
2359) -> i32;
2360
2361/// Emits a `nontemporal` store, which gives a hint to the CPU that the data should not be held
2362/// in cache. Except for performance, this is fully equivalent to `ptr.write(val)`.
2363///
2364/// Not all architectures provide such an operation. For instance, x86 does not: while `MOVNT`
2365/// exists, that operation is *not* equivalent to `ptr.write(val)` (`MOVNT` writes can be reordered
2366/// in ways that are not allowed for regular writes).
2367#[rustc_intrinsic]
2368#[rustc_nounwind]
2369#[cfg(not(feature = "ferrocene_subset"))]
2370pub unsafe fn nontemporal_store<T>(ptr: *mut T, val: T);
2371
2372/// See documentation of `<*const T>::offset_from` for details.
2373#[rustc_intrinsic_const_stable_indirect]
2374#[rustc_nounwind]
2375#[rustc_intrinsic]
2376#[cfg(not(feature = "ferrocene_subset"))]
2377pub const unsafe fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
2378
2379/// See documentation of `<*const T>::offset_from_unsigned` for details.
2380#[rustc_nounwind]
2381#[rustc_intrinsic]
2382#[rustc_intrinsic_const_stable_indirect]
2383pub const unsafe fn ptr_offset_from_unsigned<T>(ptr: *const T, base: *const T) -> usize;
2384
2385/// See documentation of `<*const T>::guaranteed_eq` for details.
2386/// Returns `2` if the result is unknown.
2387/// Returns `1` if the pointers are guaranteed equal.
2388/// Returns `0` if the pointers are guaranteed inequal.
2389#[rustc_intrinsic]
2390#[rustc_nounwind]
2391#[rustc_do_not_const_check]
2392#[inline]
2393#[miri::intrinsic_fallback_is_spec]
2394pub const fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8 {
2395    (ptr == other) as u8
2396}
2397
2398/// Determines whether the raw bytes of the two values are equal.
2399///
2400/// This is particularly handy for arrays, since it allows things like just
2401/// comparing `i96`s instead of forcing `alloca`s for `[6 x i16]`.
2402///
2403/// Above some backend-decided threshold this will emit calls to `memcmp`,
2404/// like slice equality does, instead of causing massive code size.
2405///
2406/// Since this works by comparing the underlying bytes, the actual `T` is
2407/// not particularly important.  It will be used for its size and alignment,
2408/// but any validity restrictions will be ignored, not enforced.
2409///
2410/// # Safety
2411///
2412/// It's UB to call this if any of the *bytes* in `*a` or `*b` are uninitialized.
2413/// Note that this is a stricter criterion than just the *values* being
2414/// fully-initialized: if `T` has padding, it's UB to call this intrinsic.
2415///
2416/// At compile-time, it is furthermore UB to call this if any of the bytes
2417/// in `*a` or `*b` have provenance.
2418///
2419/// (The implementation is allowed to branch on the results of comparisons,
2420/// which is UB if any of their inputs are `undef`.)
2421#[rustc_nounwind]
2422#[rustc_intrinsic]
2423#[cfg(not(feature = "ferrocene_subset"))]
2424pub const unsafe fn raw_eq<T>(a: &T, b: &T) -> bool;
2425
2426/// Lexicographically compare `[left, left + bytes)` and `[right, right + bytes)`
2427/// as unsigned bytes, returning negative if `left` is less, zero if all the
2428/// bytes match, or positive if `left` is greater.
2429///
2430/// This underlies things like `<[u8]>::cmp`, and will usually lower to `memcmp`.
2431///
2432/// # Safety
2433///
2434/// `left` and `right` must each be [valid] for reads of `bytes` bytes.
2435///
2436/// Note that this applies to the whole range, not just until the first byte
2437/// that differs.  That allows optimizations that can read in large chunks.
2438///
2439/// [valid]: crate::ptr#safety
2440#[rustc_nounwind]
2441#[rustc_intrinsic]
2442#[rustc_const_unstable(feature = "const_cmp", issue = "143800")]
2443pub const unsafe fn compare_bytes(left: *const u8, right: *const u8, bytes: usize) -> i32;
2444
2445/// See documentation of [`std::hint::black_box`] for details.
2446///
2447/// [`std::hint::black_box`]: crate::hint::black_box
2448#[rustc_nounwind]
2449#[rustc_intrinsic]
2450#[rustc_intrinsic_const_stable_indirect]
2451#[cfg(not(feature = "ferrocene_subset"))]
2452pub const fn black_box<T>(dummy: T) -> T;
2453
2454/// Selects which function to call depending on the context.
2455///
2456/// If this function is evaluated at compile-time, then a call to this
2457/// intrinsic will be replaced with a call to `called_in_const`. It gets
2458/// replaced with a call to `called_at_rt` otherwise.
2459///
2460/// This function is safe to call, but note the stability concerns below.
2461///
2462/// # Type Requirements
2463///
2464/// The two functions must be both function items. They cannot be function
2465/// pointers or closures. The first function must be a `const fn`.
2466///
2467/// `arg` will be the tupled arguments that will be passed to either one of
2468/// the two functions, therefore, both functions must accept the same type of
2469/// arguments. Both functions must return RET.
2470///
2471/// # Stability concerns
2472///
2473/// Rust has not yet decided that `const fn` are allowed to tell whether
2474/// they run at compile-time or at runtime. Therefore, when using this
2475/// intrinsic anywhere that can be reached from stable, it is crucial that
2476/// the end-to-end behavior of the stable `const fn` is the same for both
2477/// modes of execution. (Here, Undefined Behavior is considered "the same"
2478/// as any other behavior, so if the function exhibits UB at runtime then
2479/// it may do whatever it wants at compile-time.)
2480///
2481/// Here is an example of how this could cause a problem:
2482/// ```no_run
2483/// #![feature(const_eval_select)]
2484/// #![feature(core_intrinsics)]
2485/// # #![allow(internal_features)]
2486/// use std::intrinsics::const_eval_select;
2487///
2488/// // Standard library
2489/// pub const fn inconsistent() -> i32 {
2490///     fn runtime() -> i32 { 1 }
2491///     const fn compiletime() -> i32 { 2 }
2492///
2493///     // ⚠ This code violates the required equivalence of `compiletime`
2494///     // and `runtime`.
2495///     const_eval_select((), compiletime, runtime)
2496/// }
2497///
2498/// // User Crate
2499/// const X: i32 = inconsistent();
2500/// let x = inconsistent();
2501/// assert_eq!(x, X);
2502/// ```
2503///
2504/// Currently such an assertion would always succeed; until Rust decides
2505/// otherwise, that principle should not be violated.
2506#[rustc_const_unstable(feature = "const_eval_select", issue = "124625")]
2507#[rustc_intrinsic]
2508pub const fn const_eval_select<ARG: Tuple, F, G, RET>(
2509    _arg: ARG,
2510    _called_in_const: F,
2511    _called_at_rt: G,
2512) -> RET
2513where
2514    G: FnOnce<ARG, Output = RET>,
2515    F: const FnOnce<ARG, Output = RET>;
2516
2517/// A macro to make it easier to invoke const_eval_select. Use as follows:
2518/// ```rust,ignore (just a macro example)
2519/// const_eval_select!(
2520///     @capture { arg1: i32 = some_expr, arg2: T = other_expr } -> U:
2521///     if const #[attributes_for_const_arm] {
2522///         // Compile-time code goes here.
2523///     } else #[attributes_for_runtime_arm] {
2524///         // Run-time code goes here.
2525///     }
2526/// )
2527/// ```
2528/// The `@capture` block declares which surrounding variables / expressions can be
2529/// used inside the `if const`.
2530/// Note that the two arms of this `if` really each become their own function, which is why the
2531/// macro supports setting attributes for those functions. Both functions are marked as `#[inline]`.
2532///
2533/// See [`const_eval_select()`] for the rules and requirements around that intrinsic.
2534pub(crate) macro const_eval_select {
2535    (
2536        @capture$([$($binders:tt)*])? { $($arg:ident : $ty:ty = $val:expr),* $(,)? } $( -> $ret:ty )? :
2537        if const
2538            $(#[$compiletime_attr:meta])* $compiletime:block
2539        else
2540            $(#[$runtime_attr:meta])* $runtime:block
2541    ) => {{
2542        #[inline]
2543        $(#[$runtime_attr])*
2544        fn runtime$(<$($binders)*>)?($($arg: $ty),*) $( -> $ret )? {
2545            $runtime
2546        }
2547
2548        #[inline]
2549        $(#[$compiletime_attr])*
2550        #[ferrocene::annotation("Cannot be covered as this only runs during compilation.")]
2551        const fn compiletime$(<$($binders)*>)?($($arg: $ty),*) $( -> $ret )? {
2552            // Don't warn if one of the arguments is unused.
2553            $(let _ = $arg;)*
2554
2555            $compiletime
2556        }
2557
2558        const_eval_select(($($val,)*), compiletime, runtime)
2559    }},
2560    // We support leaving away the `val` expressions for *all* arguments
2561    // (but not for *some* arguments, that's too tricky).
2562    (
2563        @capture$([$($binders:tt)*])? { $($arg:ident : $ty:ty),* $(,)? } $( -> $ret:ty )? :
2564        if const
2565            $(#[$compiletime_attr:meta])* $compiletime:block
2566        else
2567            $(#[$runtime_attr:meta])* $runtime:block
2568    ) => {
2569        $crate::intrinsics::const_eval_select!(
2570            @capture$([$($binders)*])? { $($arg : $ty = $arg),* } $(-> $ret)? :
2571            if const
2572                $(#[$compiletime_attr])* $compiletime
2573            else
2574                $(#[$runtime_attr])* $runtime
2575        )
2576    },
2577}
2578
2579/// Returns whether the argument's value is statically known at
2580/// compile-time.
2581///
2582/// This is useful when there is a way of writing the code that will
2583/// be *faster* when some variables have known values, but *slower*
2584/// in the general case: an `if is_val_statically_known(var)` can be used
2585/// to select between these two variants. The `if` will be optimized away
2586/// and only the desired branch remains.
2587///
2588/// Formally speaking, this function non-deterministically returns `true`
2589/// or `false`, and the caller has to ensure sound behavior for both cases.
2590/// In other words, the following code has *Undefined Behavior*:
2591///
2592/// ```no_run
2593/// #![feature(core_intrinsics)]
2594/// # #![allow(internal_features)]
2595/// use std::hint::unreachable_unchecked;
2596/// use std::intrinsics::is_val_statically_known;
2597///
2598/// if !is_val_statically_known(0) { unsafe { unreachable_unchecked(); } }
2599/// ```
2600///
2601/// This also means that the following code's behavior is unspecified; it
2602/// may panic, or it may not:
2603///
2604/// ```no_run
2605/// #![feature(core_intrinsics)]
2606/// # #![allow(internal_features)]
2607/// use std::intrinsics::is_val_statically_known;
2608///
2609/// assert_eq!(is_val_statically_known(0), is_val_statically_known(0));
2610/// ```
2611///
2612/// Unsafe code may not rely on `is_val_statically_known` returning any
2613/// particular value, ever. However, the compiler will generally make it
2614/// return `true` only if the value of the argument is actually known.
2615///
2616/// # Stability concerns
2617///
2618/// While it is safe to call, this intrinsic may behave differently in
2619/// a `const` context than otherwise. See the [`const_eval_select()`]
2620/// documentation for an explanation of the issues this can cause. Unlike
2621/// `const_eval_select`, this intrinsic isn't guaranteed to behave
2622/// deterministically even in a `const` context.
2623///
2624/// # Type Requirements
2625///
2626/// `T` must be either a `bool`, a `char`, a primitive numeric type (e.g. `f32`,
2627/// but not `NonZeroISize`), or any thin pointer (e.g. `*mut String`).
2628/// Any other argument types *may* cause a compiler error.
2629///
2630/// ## Pointers
2631///
2632/// When the input is a pointer, only the pointer itself is
2633/// ever considered. The pointee has no effect. Currently, these functions
2634/// behave identically:
2635///
2636/// ```
2637/// #![feature(core_intrinsics)]
2638/// # #![allow(internal_features)]
2639/// use std::intrinsics::is_val_statically_known;
2640///
2641/// fn foo(x: &i32) -> bool {
2642///     is_val_statically_known(x)
2643/// }
2644///
2645/// fn bar(x: &i32) -> bool {
2646///     is_val_statically_known(
2647///         (x as *const i32).addr()
2648///     )
2649/// }
2650/// # _ = foo(&5_i32);
2651/// # _ = bar(&5_i32);
2652/// ```
2653#[rustc_const_stable_indirect]
2654#[rustc_nounwind]
2655#[unstable(feature = "core_intrinsics", issue = "none")]
2656#[rustc_intrinsic]
2657pub const fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
2658    false
2659}
2660
2661/// Non-overlapping *typed* swap of a single value.
2662///
2663/// The codegen backends will replace this with a better implementation when
2664/// `T` is a simple type that can be loaded and stored as an immediate.
2665///
2666/// The stabilized form of this intrinsic is [`crate::mem::swap`].
2667///
2668/// # Safety
2669/// Behavior is undefined if any of the following conditions are violated:
2670///
2671/// * Both `x` and `y` must be [valid] for both reads and writes.
2672///
2673/// * Both `x` and `y` must be properly aligned.
2674///
2675/// * The region of memory beginning at `x` must *not* overlap with the region of memory
2676///   beginning at `y`.
2677///
2678/// * The memory pointed by `x` and `y` must both contain values of type `T`.
2679///
2680/// [valid]: crate::ptr#safety
2681#[rustc_nounwind]
2682#[inline]
2683#[rustc_intrinsic]
2684#[rustc_intrinsic_const_stable_indirect]
2685pub const unsafe fn typed_swap_nonoverlapping<T>(x: *mut T, y: *mut T) {
2686    // SAFETY: The caller provided single non-overlapping items behind
2687    // pointers, so swapping them with `count: 1` is fine.
2688    unsafe { ptr::swap_nonoverlapping(x, y, 1) };
2689}
2690
2691/// Returns whether we should perform some UB-checking at runtime. This eventually evaluates to
2692/// `cfg!(ub_checks)`, but behaves different from `cfg!` when mixing crates built with different
2693/// flags: if the crate has UB checks enabled or carries the `#[rustc_preserve_ub_checks]`
2694/// attribute, evaluation is delayed until monomorphization (or until the call gets inlined into
2695/// a crate that does not delay evaluation further); otherwise it can happen any time.
2696///
2697/// The common case here is a user program built with ub_checks linked against the distributed
2698/// sysroot which is built without ub_checks but with `#[rustc_preserve_ub_checks]`.
2699/// For code that gets monomorphized in the user crate (i.e., generic functions and functions with
2700/// `#[inline]`), gating assertions on `ub_checks()` rather than `cfg!(ub_checks)` means that
2701/// assertions are enabled whenever the *user crate* has UB checks enabled. However, if the
2702/// user has UB checks disabled, the checks will still get optimized out. This intrinsic is
2703/// primarily used by [`crate::ub_checks::assert_unsafe_precondition`].
2704#[rustc_intrinsic_const_stable_indirect] // just for UB checks
2705#[inline(always)]
2706#[rustc_intrinsic]
2707#[ferrocene::annotation(
2708    "This function is always used in `assert_unsafe_precondition` which produces an unwinding panic, meaning that we cannot cover it."
2709)]
2710pub const fn ub_checks() -> bool {
2711    cfg!(ub_checks)
2712}
2713
2714/// Returns whether we should perform some overflow-checking at runtime. This eventually evaluates to
2715/// `cfg!(overflow_checks)`, but behaves different from `cfg!` when mixing crates built with different
2716/// flags: if the crate has overflow checks enabled or carries the `#[rustc_inherit_overflow_checks]`
2717/// attribute, evaluation is delayed until monomorphization (or until the call gets inlined into
2718/// a crate that does not delay evaluation further); otherwise it can happen any time.
2719///
2720/// The common case here is a user program built with overflow_checks linked against the distributed
2721/// sysroot which is built without overflow_checks but with `#[rustc_inherit_overflow_checks]`.
2722/// For code that gets monomorphized in the user crate (i.e., generic functions and functions with
2723/// `#[inline]`), gating assertions on `overflow_checks()` rather than `cfg!(overflow_checks)` means that
2724/// assertions are enabled whenever the *user crate* has overflow checks enabled. However if the
2725/// user has overflow checks disabled, the checks will still get optimized out.
2726#[inline(always)]
2727#[rustc_intrinsic]
2728#[ferrocene::annotation(
2729    "This function cannot trivially be tested since it depends on the build configuration. It was manually reviewed."
2730)]
2731pub const fn overflow_checks() -> bool {
2732    cfg!(debug_assertions)
2733}
2734
2735/// Allocates a block of memory at compile time.
2736/// At runtime, just returns a null pointer.
2737///
2738/// # Safety
2739///
2740/// - The `align` argument must be a power of two.
2741///    - At compile time, a compile error occurs if this constraint is violated.
2742///    - At runtime, it is not checked.
2743#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
2744#[rustc_nounwind]
2745#[rustc_intrinsic]
2746#[miri::intrinsic_fallback_is_spec]
2747#[cfg(not(feature = "ferrocene_subset"))]
2748pub const unsafe fn const_allocate(_size: usize, _align: usize) -> *mut u8 {
2749    // const eval overrides this function, but runtime code for now just returns null pointers.
2750    // See <https://github.com/rust-lang/rust/issues/93935>.
2751    crate::ptr::null_mut()
2752}
2753
2754/// Deallocates a memory which allocated by `intrinsics::const_allocate` at compile time.
2755/// At runtime, it does nothing.
2756///
2757/// # Safety
2758///
2759/// - The `align` argument must be a power of two.
2760///    - At compile time, a compile error occurs if this constraint is violated.
2761///    - At runtime, it is not checked.
2762/// - If the `ptr` is created in an another const, this intrinsic doesn't deallocate it.
2763/// - If the `ptr` is pointing to a local variable, this intrinsic doesn't deallocate it.
2764#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
2765#[unstable(feature = "core_intrinsics", issue = "none")]
2766#[rustc_nounwind]
2767#[rustc_intrinsic]
2768#[miri::intrinsic_fallback_is_spec]
2769#[cfg(not(feature = "ferrocene_subset"))]
2770pub const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {
2771    // Runtime NOP
2772}
2773
2774/// Convert the allocation this pointer points to into immutable global memory.
2775/// The pointer must point to the beginning of a heap allocation.
2776/// This operation only makes sense during compile time. At runtime, it does nothing.
2777#[rustc_const_unstable(feature = "const_heap", issue = "79597")]
2778#[rustc_nounwind]
2779#[rustc_intrinsic]
2780#[miri::intrinsic_fallback_is_spec]
2781#[ferrocene::annotation("This function is also a noop in runtime so we can't cover it currently.")]
2782pub const unsafe fn const_make_global(ptr: *mut u8) -> *const u8 {
2783    // const eval overrides this function; at runtime, it is a NOP.
2784    ptr
2785}
2786
2787/// Check if the pre-condition `cond` has been met.
2788///
2789/// By default, if `contract_checks` is enabled, this will panic with no unwind if the condition
2790/// returns false.
2791///
2792/// Note that this function is a no-op during constant evaluation.
2793#[unstable(feature = "contracts_internals", issue = "128044")]
2794// Calls to this function get inserted by an AST expansion pass, which uses the equivalent of
2795// `#[allow_internal_unstable]` to allow using `contracts_internals` functions. Const-checking
2796// doesn't honor `#[allow_internal_unstable]`, so for the const feature gate we use the user-facing
2797// `contracts` feature rather than the perma-unstable `contracts_internals`
2798#[rustc_const_unstable(feature = "contracts", issue = "128044")]
2799#[lang = "contract_check_requires"]
2800#[rustc_intrinsic]
2801#[cfg(not(feature = "ferrocene_subset"))]
2802pub const fn contract_check_requires<C: Fn() -> bool + Copy>(cond: C) {
2803    const_eval_select!(
2804        @capture[C: Fn() -> bool + Copy] { cond: C } :
2805        if const {
2806                // Do nothing
2807        } else {
2808            if !cond() {
2809                // Emit no unwind panic in case this was a safety requirement.
2810                crate::panicking::panic_nounwind("failed requires check");
2811            }
2812        }
2813    )
2814}
2815
2816/// Check if the post-condition `cond` has been met.
2817///
2818/// By default, if `contract_checks` is enabled, this will panic with no unwind if the condition
2819/// returns false.
2820///
2821/// If `cond` is `None`, then no postcondition checking is performed.
2822///
2823/// Note that this function is a no-op during constant evaluation.
2824#[unstable(feature = "contracts_internals", issue = "128044")]
2825// Similar to `contract_check_requires`, we need to use the user-facing
2826// `contracts` feature rather than the perma-unstable `contracts_internals`.
2827// Const-checking doesn't honor allow_internal_unstable logic used by contract expansion.
2828#[rustc_const_unstable(feature = "contracts", issue = "128044")]
2829#[lang = "contract_check_ensures"]
2830#[rustc_intrinsic]
2831#[cfg(not(feature = "ferrocene_subset"))]
2832pub const fn contract_check_ensures<C: Fn(&Ret) -> bool + Copy, Ret>(
2833    cond: Option<C>,
2834    ret: Ret,
2835) -> Ret {
2836    const_eval_select!(
2837        @capture[C: Fn(&Ret) -> bool + Copy, Ret] { cond: Option<C>, ret: Ret } -> Ret :
2838        if const {
2839            // Do nothing
2840            ret
2841        } else {
2842            match cond {
2843                crate::option::Option::Some(cond) => {
2844                    if !cond(&ret) {
2845                        // Emit no unwind panic in case this was a safety requirement.
2846                        crate::panicking::panic_nounwind("failed ensures check");
2847                    }
2848                },
2849                crate::option::Option::None => {},
2850            }
2851            ret
2852        }
2853    )
2854}
2855
2856/// The intrinsic will return the size stored in that vtable.
2857///
2858/// # Safety
2859///
2860/// `ptr` must point to a vtable.
2861#[rustc_nounwind]
2862#[unstable(feature = "core_intrinsics", issue = "none")]
2863#[rustc_intrinsic]
2864#[cfg(not(feature = "ferrocene_subset"))]
2865pub unsafe fn vtable_size(ptr: *const ()) -> usize;
2866
2867/// The intrinsic will return the alignment stored in that vtable.
2868///
2869/// # Safety
2870///
2871/// `ptr` must point to a vtable.
2872#[rustc_nounwind]
2873#[unstable(feature = "core_intrinsics", issue = "none")]
2874#[rustc_intrinsic]
2875#[cfg(not(feature = "ferrocene_subset"))]
2876pub unsafe fn vtable_align(ptr: *const ()) -> usize;
2877
2878/// The intrinsic returns the `U` vtable for `T` if `T` can be coerced to the trait object type `U`.
2879///
2880/// # Compile-time failures
2881/// Determining whether `T` can be coerced to the trait object type `U` requires trait resolution by the compiler.
2882/// In some cases, that resolution can exceed the recursion limit,
2883/// and compilation will fail instead of this function returning `None`.
2884#[rustc_nounwind]
2885#[unstable(feature = "core_intrinsics", issue = "none")]
2886#[rustc_intrinsic]
2887pub const fn vtable_for<T, U: ptr::Pointee<Metadata = ptr::DynMetadata<U>> + ?Sized>()
2888-> Option<ptr::DynMetadata<U>>;
2889
2890/// The size of a type in bytes.
2891///
2892/// Note that, unlike most intrinsics, this is safe to call;
2893/// it does not require an `unsafe` block.
2894/// Therefore, implementations must not require the user to uphold
2895/// any safety invariants.
2896///
2897/// More specifically, this is the offset in bytes between successive
2898/// items of the same type, including alignment padding.
2899///
2900/// Note that, unlike most intrinsics, this can only be called at compile-time
2901/// as backends do not have an implementation for it. The only caller (its
2902/// stable counterpart) wraps this intrinsic call in a `const` block so that
2903/// backends only see an evaluated constant.
2904///
2905/// The stabilized version of this intrinsic is [`core::mem::size_of`].
2906#[rustc_nounwind]
2907#[unstable(feature = "core_intrinsics", issue = "none")]
2908#[rustc_intrinsic_const_stable_indirect]
2909#[rustc_intrinsic]
2910pub const fn size_of<T>() -> usize;
2911
2912/// The minimum alignment of a type.
2913///
2914/// Note that, unlike most intrinsics, this is safe to call;
2915/// it does not require an `unsafe` block.
2916/// Therefore, implementations must not require the user to uphold
2917/// any safety invariants.
2918///
2919/// Note that, unlike most intrinsics, this can only be called at compile-time
2920/// as backends do not have an implementation for it. The only caller (its
2921/// stable counterpart) wraps this intrinsic call in a `const` block so that
2922/// backends only see an evaluated constant.
2923///
2924/// The stabilized version of this intrinsic is [`core::mem::align_of`].
2925#[rustc_nounwind]
2926#[unstable(feature = "core_intrinsics", issue = "none")]
2927#[rustc_intrinsic_const_stable_indirect]
2928#[rustc_intrinsic]
2929pub const fn align_of<T>() -> usize;
2930
2931/// The offset of a field inside a type.
2932///
2933/// Note that, unlike most intrinsics, this is safe to call;
2934/// it does not require an `unsafe` block.
2935/// Therefore, implementations must not require the user to uphold
2936/// any safety invariants.
2937///
2938/// This intrinsic can only be evaluated at compile-time, and should only appear in
2939/// constants or inline const blocks.
2940///
2941/// The stabilized version of this intrinsic is [`core::mem::offset_of`].
2942/// This intrinsic is also a lang item so `offset_of!` can desugar to calls to it.
2943#[rustc_nounwind]
2944#[unstable(feature = "core_intrinsics", issue = "none")]
2945#[rustc_const_unstable(feature = "core_intrinsics", issue = "none")]
2946#[rustc_intrinsic_const_stable_indirect]
2947#[rustc_intrinsic]
2948#[lang = "offset_of"]
2949pub const fn offset_of<T: PointeeSized>(variant: u32, field: u32) -> usize;
2950
2951/// Returns the number of variants of the type `T` cast to a `usize`;
2952/// if `T` has no variants, returns `0`. Uninhabited variants will be counted.
2953///
2954/// Note that, unlike most intrinsics, this can only be called at compile-time
2955/// as backends do not have an implementation for it. The only caller (its
2956/// stable counterpart) wraps this intrinsic call in a `const` block so that
2957/// backends only see an evaluated constant.
2958///
2959/// The to-be-stabilized version of this intrinsic is [`crate::mem::variant_count`].
2960#[rustc_nounwind]
2961#[unstable(feature = "core_intrinsics", issue = "none")]
2962#[rustc_intrinsic]
2963#[cfg(not(feature = "ferrocene_subset"))]
2964pub const fn variant_count<T>() -> usize;
2965
2966/// The size of the referenced value in bytes.
2967///
2968/// The stabilized version of this intrinsic is [`core::mem::size_of_val`].
2969///
2970/// # Safety
2971///
2972/// See [`crate::mem::size_of_val_raw`] for safety conditions.
2973#[rustc_nounwind]
2974#[unstable(feature = "core_intrinsics", issue = "none")]
2975#[rustc_intrinsic]
2976#[rustc_intrinsic_const_stable_indirect]
2977pub const unsafe fn size_of_val<T: ?Sized>(ptr: *const T) -> usize;
2978
2979/// The required alignment of the referenced value.
2980///
2981/// The stabilized version of this intrinsic is [`core::mem::align_of_val`].
2982///
2983/// # Safety
2984///
2985/// See [`crate::mem::align_of_val_raw`] for safety conditions.
2986#[rustc_nounwind]
2987#[unstable(feature = "core_intrinsics", issue = "none")]
2988#[rustc_intrinsic]
2989#[rustc_intrinsic_const_stable_indirect]
2990pub const unsafe fn align_of_val<T: ?Sized>(ptr: *const T) -> usize;
2991
2992/// Compute the type information of a concrete type.
2993/// It can only be called at compile time, the backends do
2994/// not implement it.
2995#[cfg(not(feature = "ferrocene_subset"))]
2996#[rustc_intrinsic]
2997#[unstable(feature = "core_intrinsics", issue = "none")]
2998pub const fn type_of(_id: crate::any::TypeId) -> crate::mem::type_info::Type {
2999    panic!("`TypeId::info` can only be called at compile-time")
3000}
3001
3002/// Gets a static string slice containing the name of a type.
3003///
3004/// Note that, unlike most intrinsics, this can only be called at compile-time
3005/// as backends do not have an implementation for it. The only caller (its
3006/// stable counterpart) wraps this intrinsic call in a `const` block so that
3007/// backends only see an evaluated constant.
3008///
3009/// The stabilized version of this intrinsic is [`core::any::type_name`].
3010#[rustc_nounwind]
3011#[unstable(feature = "core_intrinsics", issue = "none")]
3012#[rustc_intrinsic]
3013pub const fn type_name<T: ?Sized>() -> &'static str;
3014
3015/// Gets an identifier which is globally unique to the specified type. This
3016/// function will return the same value for a type regardless of whichever
3017/// crate it is invoked in.
3018///
3019/// Note that, unlike most intrinsics, this can only be called at compile-time
3020/// as backends do not have an implementation for it. The only caller (its
3021/// stable counterpart) wraps this intrinsic call in a `const` block so that
3022/// backends only see an evaluated constant.
3023///
3024/// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
3025#[rustc_nounwind]
3026#[unstable(feature = "core_intrinsics", issue = "none")]
3027#[rustc_intrinsic]
3028pub const fn type_id<T: ?Sized>() -> crate::any::TypeId;
3029
3030/// Tests (at compile-time) if two [`crate::any::TypeId`] instances identify the
3031/// same type. This is necessary because at const-eval time the actual discriminating
3032/// data is opaque and cannot be inspected directly.
3033///
3034/// The stabilized version of this intrinsic is the [PartialEq] impl for [`core::any::TypeId`].
3035#[rustc_nounwind]
3036#[unstable(feature = "core_intrinsics", issue = "none")]
3037#[rustc_intrinsic]
3038#[rustc_do_not_const_check]
3039#[ferrocene::annotation("Cannot be covered as this code cannot be reached during runtime.")]
3040pub const fn type_id_eq(a: crate::any::TypeId, b: crate::any::TypeId) -> bool {
3041    a.data == b.data
3042}
3043
3044/// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`.
3045///
3046/// This is used to implement functions like `slice::from_raw_parts_mut` and
3047/// `ptr::from_raw_parts` in a way compatible with the compiler being able to
3048/// change the possible layouts of pointers.
3049#[rustc_nounwind]
3050#[unstable(feature = "core_intrinsics", issue = "none")]
3051#[rustc_intrinsic_const_stable_indirect]
3052#[rustc_intrinsic]
3053pub const fn aggregate_raw_ptr<P: bounds::BuiltinDeref, D, M>(data: D, meta: M) -> P
3054where
3055    <P as bounds::BuiltinDeref>::Pointee: ptr::Pointee<Metadata = M>;
3056
3057/// Lowers in MIR to `Rvalue::UnaryOp` with `UnOp::PtrMetadata`.
3058///
3059/// This is used to implement functions like `ptr::metadata`.
3060#[rustc_nounwind]
3061#[unstable(feature = "core_intrinsics", issue = "none")]
3062#[rustc_intrinsic_const_stable_indirect]
3063#[rustc_intrinsic]
3064pub const fn ptr_metadata<P: ptr::Pointee<Metadata = M> + PointeeSized, M>(ptr: *const P) -> M;
3065
3066/// This is an accidentally-stable alias to [`ptr::copy_nonoverlapping`]; use that instead.
3067// Note (intentionally not in the doc comment): `ptr::copy_nonoverlapping` adds some extra
3068// debug assertions; if you are writing compiler tests or code inside the standard library
3069// that wants to avoid those debug assertions, directly call this intrinsic instead.
3070#[stable(feature = "rust1", since = "1.0.0")]
3071#[rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead"]
3072#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
3073#[rustc_nounwind]
3074#[rustc_intrinsic]
3075pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
3076
3077/// This is an accidentally-stable alias to [`ptr::copy`]; use that instead.
3078// Note (intentionally not in the doc comment): `ptr::copy` adds some extra
3079// debug assertions; if you are writing compiler tests or code inside the standard library
3080// that wants to avoid those debug assertions, directly call this intrinsic instead.
3081#[stable(feature = "rust1", since = "1.0.0")]
3082#[rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead"]
3083#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
3084#[rustc_nounwind]
3085#[rustc_intrinsic]
3086pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize);
3087
3088/// This is an accidentally-stable alias to [`ptr::write_bytes`]; use that instead.
3089// Note (intentionally not in the doc comment): `ptr::write_bytes` adds some extra
3090// debug assertions; if you are writing compiler tests or code inside the standard library
3091// that wants to avoid those debug assertions, directly call this intrinsic instead.
3092#[stable(feature = "rust1", since = "1.0.0")]
3093#[rustc_allowed_through_unstable_modules = "import this function via `std::ptr` instead"]
3094#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.83.0")]
3095#[rustc_nounwind]
3096#[rustc_intrinsic]
3097pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
3098
3099/// Returns the minimum of two `f16` values, ignoring NaN.
3100///
3101/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
3102/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
3103/// and `-0.0`), either input may be returned non-deterministically.
3104///
3105/// Note that, unlike most intrinsics, this is safe to call;
3106/// it does not require an `unsafe` block.
3107/// Therefore, implementations must not require the user to uphold
3108/// any safety invariants.
3109///
3110/// The stabilized version of this intrinsic is [`f16::min`].
3111#[rustc_nounwind]
3112#[rustc_intrinsic]
3113#[cfg(not(feature = "ferrocene_subset"))]
3114pub const fn minnumf16(x: f16, y: f16) -> f16;
3115
3116/// Returns the minimum of two `f32` values, ignoring NaN.
3117///
3118/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
3119/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
3120/// and `-0.0`), either input may be returned non-deterministically.
3121///
3122/// Note that, unlike most intrinsics, this is safe to call;
3123/// it does not require an `unsafe` block.
3124/// Therefore, implementations must not require the user to uphold
3125/// any safety invariants.
3126///
3127/// The stabilized version of this intrinsic is [`f32::min`].
3128#[rustc_nounwind]
3129#[rustc_intrinsic_const_stable_indirect]
3130#[rustc_intrinsic]
3131pub const fn minnumf32(x: f32, y: f32) -> f32;
3132
3133/// Returns the minimum of two `f64` values, ignoring NaN.
3134///
3135/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
3136/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
3137/// and `-0.0`), either input may be returned non-deterministically.
3138///
3139/// Note that, unlike most intrinsics, this is safe to call;
3140/// it does not require an `unsafe` block.
3141/// Therefore, implementations must not require the user to uphold
3142/// any safety invariants.
3143///
3144/// The stabilized version of this intrinsic is [`f64::min`].
3145#[rustc_nounwind]
3146#[rustc_intrinsic_const_stable_indirect]
3147#[rustc_intrinsic]
3148#[cfg(not(feature = "ferrocene_subset"))]
3149pub const fn minnumf64(x: f64, y: f64) -> f64;
3150
3151/// Returns the minimum of two `f128` values, ignoring NaN.
3152///
3153/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
3154/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
3155/// and `-0.0`), either input may be returned non-deterministically.
3156///
3157/// Note that, unlike most intrinsics, this is safe to call;
3158/// it does not require an `unsafe` block.
3159/// Therefore, implementations must not require the user to uphold
3160/// any safety invariants.
3161///
3162/// The stabilized version of this intrinsic is [`f128::min`].
3163#[rustc_nounwind]
3164#[rustc_intrinsic]
3165#[cfg(not(feature = "ferrocene_subset"))]
3166pub const fn minnumf128(x: f128, y: f128) -> f128;
3167
3168/// Returns the minimum of two `f16` values, propagating NaN.
3169///
3170/// This behaves like IEEE 754-2019 minimum. In particular:
3171/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3172/// For this operation, -0.0 is considered to be strictly less than +0.0.
3173///
3174/// Note that, unlike most intrinsics, this is safe to call;
3175/// it does not require an `unsafe` block.
3176/// Therefore, implementations must not require the user to uphold
3177/// any safety invariants.
3178#[rustc_nounwind]
3179#[rustc_intrinsic]
3180#[cfg(not(feature = "ferrocene_subset"))]
3181pub const fn minimumf16(x: f16, y: f16) -> f16 {
3182    if x < y {
3183        x
3184    } else if y < x {
3185        y
3186    } else if x == y {
3187        if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
3188    } else {
3189        // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
3190        x + y
3191    }
3192}
3193
3194/// Returns the minimum of two `f32` values, propagating NaN.
3195///
3196/// This behaves like IEEE 754-2019 minimum. In particular:
3197/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3198/// For this operation, -0.0 is considered to be strictly less than +0.0.
3199///
3200/// Note that, unlike most intrinsics, this is safe to call;
3201/// it does not require an `unsafe` block.
3202/// Therefore, implementations must not require the user to uphold
3203/// any safety invariants.
3204#[rustc_nounwind]
3205#[rustc_intrinsic]
3206#[cfg(not(feature = "ferrocene_subset"))]
3207pub const fn minimumf32(x: f32, y: f32) -> f32 {
3208    if x < y {
3209        x
3210    } else if y < x {
3211        y
3212    } else if x == y {
3213        if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
3214    } else {
3215        // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
3216        x + y
3217    }
3218}
3219
3220/// Returns the minimum of two `f64` values, propagating NaN.
3221///
3222/// This behaves like IEEE 754-2019 minimum. In particular:
3223/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3224/// For this operation, -0.0 is considered to be strictly less than +0.0.
3225///
3226/// Note that, unlike most intrinsics, this is safe to call;
3227/// it does not require an `unsafe` block.
3228/// Therefore, implementations must not require the user to uphold
3229/// any safety invariants.
3230#[rustc_nounwind]
3231#[rustc_intrinsic]
3232#[cfg(not(feature = "ferrocene_subset"))]
3233pub const fn minimumf64(x: f64, y: f64) -> f64 {
3234    if x < y {
3235        x
3236    } else if y < x {
3237        y
3238    } else if x == y {
3239        if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
3240    } else {
3241        // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
3242        x + y
3243    }
3244}
3245
3246/// Returns the minimum of two `f128` values, propagating NaN.
3247///
3248/// This behaves like IEEE 754-2019 minimum. In particular:
3249/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3250/// For this operation, -0.0 is considered to be strictly less than +0.0.
3251///
3252/// Note that, unlike most intrinsics, this is safe to call;
3253/// it does not require an `unsafe` block.
3254/// Therefore, implementations must not require the user to uphold
3255/// any safety invariants.
3256#[rustc_nounwind]
3257#[rustc_intrinsic]
3258#[cfg(not(feature = "ferrocene_subset"))]
3259pub const fn minimumf128(x: f128, y: f128) -> f128 {
3260    if x < y {
3261        x
3262    } else if y < x {
3263        y
3264    } else if x == y {
3265        if x.is_sign_negative() && y.is_sign_positive() { x } else { y }
3266    } else {
3267        // At least one input is NaN. Use `+` to perform NaN propagation and quieting.
3268        x + y
3269    }
3270}
3271
3272/// Returns the maximum of two `f16` values, ignoring NaN.
3273///
3274/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
3275/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
3276/// and `-0.0`), either input may be returned non-deterministically.
3277///
3278/// Note that, unlike most intrinsics, this is safe to call;
3279/// it does not require an `unsafe` block.
3280/// Therefore, implementations must not require the user to uphold
3281/// any safety invariants.
3282///
3283/// The stabilized version of this intrinsic is [`f16::max`].
3284#[rustc_nounwind]
3285#[rustc_intrinsic]
3286#[cfg(not(feature = "ferrocene_subset"))]
3287pub const fn maxnumf16(x: f16, y: f16) -> f16;
3288
3289/// Returns the maximum of two `f32` values, ignoring NaN.
3290///
3291/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
3292/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
3293/// and `-0.0`), either input may be returned non-deterministically.
3294///
3295/// Note that, unlike most intrinsics, this is safe to call;
3296/// it does not require an `unsafe` block.
3297/// Therefore, implementations must not require the user to uphold
3298/// any safety invariants.
3299///
3300/// The stabilized version of this intrinsic is [`f32::max`].
3301#[rustc_nounwind]
3302#[rustc_intrinsic_const_stable_indirect]
3303#[rustc_intrinsic]
3304pub const fn maxnumf32(x: f32, y: f32) -> f32;
3305
3306/// Returns the maximum of two `f64` values, ignoring NaN.
3307///
3308/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
3309/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
3310/// and `-0.0`), either input may be returned non-deterministically.
3311///
3312/// Note that, unlike most intrinsics, this is safe to call;
3313/// it does not require an `unsafe` block.
3314/// Therefore, implementations must not require the user to uphold
3315/// any safety invariants.
3316///
3317/// The stabilized version of this intrinsic is [`f64::max`].
3318#[rustc_nounwind]
3319#[rustc_intrinsic_const_stable_indirect]
3320#[rustc_intrinsic]
3321#[cfg(not(feature = "ferrocene_subset"))]
3322pub const fn maxnumf64(x: f64, y: f64) -> f64;
3323
3324/// Returns the maximum of two `f128` values, ignoring NaN.
3325///
3326/// If one of the arguments is NaN (quiet or signaling), then the other argument is returned. If
3327/// both arguments are NaN, returns NaN. If the inputs compare equal (such as for the case of `+0.0`
3328/// and `-0.0`), either input may be returned non-deterministically.
3329///
3330/// Note that, unlike most intrinsics, this is safe to call;
3331/// it does not require an `unsafe` block.
3332/// Therefore, implementations must not require the user to uphold
3333/// any safety invariants.
3334///
3335/// The stabilized version of this intrinsic is [`f128::max`].
3336#[rustc_nounwind]
3337#[rustc_intrinsic]
3338#[cfg(not(feature = "ferrocene_subset"))]
3339pub const fn maxnumf128(x: f128, y: f128) -> f128;
3340
3341/// Returns the maximum of two `f16` values, propagating NaN.
3342///
3343/// This behaves like IEEE 754-2019 maximum. In particular:
3344/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3345/// For this operation, -0.0 is considered to be strictly less than +0.0.
3346///
3347/// Note that, unlike most intrinsics, this is safe to call;
3348/// it does not require an `unsafe` block.
3349/// Therefore, implementations must not require the user to uphold
3350/// any safety invariants.
3351#[rustc_nounwind]
3352#[rustc_intrinsic]
3353#[cfg(not(feature = "ferrocene_subset"))]
3354pub const fn maximumf16(x: f16, y: f16) -> f16 {
3355    if x > y {
3356        x
3357    } else if y > x {
3358        y
3359    } else if x == y {
3360        if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
3361    } else {
3362        x + y
3363    }
3364}
3365
3366/// Returns the maximum of two `f32` values, propagating NaN.
3367///
3368/// This behaves like IEEE 754-2019 maximum. In particular:
3369/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3370/// For this operation, -0.0 is considered to be strictly less than +0.0.
3371///
3372/// Note that, unlike most intrinsics, this is safe to call;
3373/// it does not require an `unsafe` block.
3374/// Therefore, implementations must not require the user to uphold
3375/// any safety invariants.
3376#[rustc_nounwind]
3377#[rustc_intrinsic]
3378#[cfg(not(feature = "ferrocene_subset"))]
3379pub const fn maximumf32(x: f32, y: f32) -> f32 {
3380    if x > y {
3381        x
3382    } else if y > x {
3383        y
3384    } else if x == y {
3385        if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
3386    } else {
3387        x + y
3388    }
3389}
3390
3391/// Returns the maximum of two `f64` values, propagating NaN.
3392///
3393/// This behaves like IEEE 754-2019 maximum. In particular:
3394/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3395/// For this operation, -0.0 is considered to be strictly less than +0.0.
3396///
3397/// Note that, unlike most intrinsics, this is safe to call;
3398/// it does not require an `unsafe` block.
3399/// Therefore, implementations must not require the user to uphold
3400/// any safety invariants.
3401#[rustc_nounwind]
3402#[rustc_intrinsic]
3403#[cfg(not(feature = "ferrocene_subset"))]
3404pub const fn maximumf64(x: f64, y: f64) -> f64 {
3405    if x > y {
3406        x
3407    } else if y > x {
3408        y
3409    } else if x == y {
3410        if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
3411    } else {
3412        x + y
3413    }
3414}
3415
3416/// Returns the maximum of two `f128` values, propagating NaN.
3417///
3418/// This behaves like IEEE 754-2019 maximum. In particular:
3419/// If one of the arguments is NaN, then a NaN is returned using the usual NaN propagation rules.
3420/// For this operation, -0.0 is considered to be strictly less than +0.0.
3421///
3422/// Note that, unlike most intrinsics, this is safe to call;
3423/// it does not require an `unsafe` block.
3424/// Therefore, implementations must not require the user to uphold
3425/// any safety invariants.
3426#[rustc_nounwind]
3427#[rustc_intrinsic]
3428#[cfg(not(feature = "ferrocene_subset"))]
3429pub const fn maximumf128(x: f128, y: f128) -> f128 {
3430    if x > y {
3431        x
3432    } else if y > x {
3433        y
3434    } else if x == y {
3435        if x.is_sign_positive() && y.is_sign_negative() { x } else { y }
3436    } else {
3437        x + y
3438    }
3439}
3440
3441/// Returns the absolute value of an `f16`.
3442///
3443/// The stabilized version of this intrinsic is
3444/// [`f16::abs`](../../std/primitive.f16.html#method.abs)
3445#[rustc_nounwind]
3446#[rustc_intrinsic]
3447pub const fn fabsf16(x: f16) -> f16;
3448
3449/// Returns the absolute value of an `f32`.
3450///
3451/// The stabilized version of this intrinsic is
3452/// [`f32::abs`](../../std/primitive.f32.html#method.abs)
3453#[rustc_nounwind]
3454#[rustc_intrinsic_const_stable_indirect]
3455#[rustc_intrinsic]
3456pub const fn fabsf32(x: f32) -> f32;
3457
3458/// Returns the absolute value of an `f64`.
3459///
3460/// The stabilized version of this intrinsic is
3461/// [`f64::abs`](../../std/primitive.f64.html#method.abs)
3462#[rustc_nounwind]
3463#[rustc_intrinsic_const_stable_indirect]
3464#[rustc_intrinsic]
3465pub const fn fabsf64(x: f64) -> f64;
3466
3467/// Returns the absolute value of an `f128`.
3468///
3469/// The stabilized version of this intrinsic is
3470/// [`f128::abs`](../../std/primitive.f128.html#method.abs)
3471#[rustc_nounwind]
3472#[rustc_intrinsic]
3473#[cfg(not(feature = "ferrocene_subset"))]
3474pub const fn fabsf128(x: f128) -> f128;
3475
3476/// Copies the sign from `y` to `x` for `f16` values.
3477///
3478/// The stabilized version of this intrinsic is
3479/// [`f16::copysign`](../../std/primitive.f16.html#method.copysign)
3480#[rustc_nounwind]
3481#[rustc_intrinsic]
3482#[cfg(not(feature = "ferrocene_subset"))]
3483pub const fn copysignf16(x: f16, y: f16) -> f16;
3484
3485/// Copies the sign from `y` to `x` for `f32` values.
3486///
3487/// The stabilized version of this intrinsic is
3488/// [`f32::copysign`](../../std/primitive.f32.html#method.copysign)
3489#[rustc_nounwind]
3490#[rustc_intrinsic_const_stable_indirect]
3491#[rustc_intrinsic]
3492pub const fn copysignf32(x: f32, y: f32) -> f32;
3493/// Copies the sign from `y` to `x` for `f64` values.
3494///
3495/// The stabilized version of this intrinsic is
3496/// [`f64::copysign`](../../std/primitive.f64.html#method.copysign)
3497#[rustc_nounwind]
3498#[rustc_intrinsic_const_stable_indirect]
3499#[rustc_intrinsic]
3500pub const fn copysignf64(x: f64, y: f64) -> f64;
3501
3502/// Copies the sign from `y` to `x` for `f128` values.
3503///
3504/// The stabilized version of this intrinsic is
3505/// [`f128::copysign`](../../std/primitive.f128.html#method.copysign)
3506#[rustc_nounwind]
3507#[rustc_intrinsic]
3508#[cfg(not(feature = "ferrocene_subset"))]
3509pub const fn copysignf128(x: f128, y: f128) -> f128;
3510
3511/// Generates the LLVM body for the automatic differentiation of `f` using Enzyme,
3512/// with `df` as the derivative function and `args` as its arguments.
3513///
3514/// Used internally as the body of `df` when expanding the `#[autodiff_forward]`
3515/// and `#[autodiff_reverse]` attribute macros.
3516///
3517/// Type Parameters:
3518/// - `F`: The original function to differentiate. Must be a function item.
3519/// - `G`: The derivative function. Must be a function item.
3520/// - `T`: A tuple of arguments passed to `df`.
3521/// - `R`: The return type of the derivative function.
3522///
3523/// This shows where the `autodiff` intrinsic is used during macro expansion:
3524///
3525/// ```rust,ignore (macro example)
3526/// #[autodiff_forward(df1, Dual, Const, Dual)]
3527/// pub fn f1(x: &[f64], y: f64) -> f64 {
3528///     unimplemented!()
3529/// }
3530/// ```
3531///
3532/// expands to:
3533///
3534/// ```rust,ignore (macro example)
3535/// #[rustc_autodiff]
3536/// #[inline(never)]
3537/// pub fn f1(x: &[f64], y: f64) -> f64 {
3538///     ::core::panicking::panic("not implemented")
3539/// }
3540/// #[rustc_autodiff(Forward, 1, Dual, Const, Dual)]
3541/// pub fn df1(x: &[f64], bx_0: &[f64], y: f64) -> (f64, f64) {
3542///     ::core::intrinsics::autodiff(f1::<>, df1::<>, (x, bx_0, y))
3543/// }
3544/// ```
3545#[rustc_nounwind]
3546#[rustc_intrinsic]
3547pub const fn autodiff<F, G, T: crate::marker::Tuple, R>(f: F, df: G, args: T) -> R;
3548
3549/// Generates the LLVM body of a wrapper function to offload a kernel `f`.
3550///
3551/// Type Parameters:
3552/// - `F`: The kernel to offload. Must be a function item.
3553/// - `T`: A tuple of arguments passed to `f`.
3554/// - `R`: The return type of the kernel.
3555///
3556/// Arguments:
3557/// - `f`: The kernel function to offload.
3558/// - `workgroup_dim`: A 3D size specifying the number of workgroups to launch.
3559/// - `thread_dim`: A 3D size specifying the number of threads per workgroup.
3560/// - `args`: A tuple of arguments forwarded to `f`.
3561///
3562/// Example usage (pseudocode):
3563///
3564/// ```rust,ignore (pseudocode)
3565/// fn kernel(x: *mut [f64; 128]) {
3566///     core::intrinsics::offload(kernel_1, [256, 1, 1], [32, 1, 1], (x,))
3567/// }
3568///
3569/// #[cfg(target_os = "linux")]
3570/// extern "C" {
3571///     pub fn kernel_1(array_b: *mut [f64; 128]);
3572/// }
3573///
3574/// #[cfg(not(target_os = "linux"))]
3575/// #[rustc_offload_kernel]
3576/// extern "gpu-kernel" fn kernel_1(x: *mut [f64; 128]) {
3577///     unsafe { (*x)[0] = 21.0 };
3578/// }
3579/// ```
3580///
3581/// For reference, see the Clang documentation on offloading:
3582/// <https://clang.llvm.org/docs/OffloadingDesign.html>.
3583#[rustc_nounwind]
3584#[rustc_intrinsic]
3585pub const fn offload<F, T: crate::marker::Tuple, R>(
3586    f: F,
3587    workgroup_dim: [u32; 3],
3588    thread_dim: [u32; 3],
3589    args: T,
3590) -> R;
3591
3592/// Inform Miri that a given pointer definitely has a certain alignment.
3593#[cfg(miri)]
3594#[rustc_allow_const_fn_unstable(const_eval_select)]
3595#[cfg(not(feature = "ferrocene_subset"))]
3596pub(crate) const fn miri_promise_symbolic_alignment(ptr: *const (), align: usize) {
3597    unsafe extern "Rust" {
3598        /// Miri-provided extern function to promise that a given pointer is properly aligned for
3599        /// "symbolic" alignment checks. Will fail if the pointer is not actually aligned or `align` is
3600        /// not a power of two. Has no effect when alignment checks are concrete (which is the default).
3601        fn miri_promise_symbolic_alignment(ptr: *const (), align: usize);
3602    }
3603
3604    const_eval_select!(
3605        @capture { ptr: *const (), align: usize}:
3606        if const {
3607            // Do nothing.
3608        } else {
3609            // SAFETY: this call is always safe.
3610            unsafe {
3611                miri_promise_symbolic_alignment(ptr, align);
3612            }
3613        }
3614    )
3615}
3616
3617/// Loads an argument of type `T` from the `va_list` `ap` and increment the
3618/// argument `ap` points to.
3619///
3620/// # Safety
3621///
3622/// This function is only sound to call when:
3623///
3624/// - there is a next variable argument available.
3625/// - the next argument's type must be ABI-compatible with the type `T`.
3626/// - the next argument must have a properly initialized value of type `T`.
3627///
3628/// Calling this function with an incompatible type, an invalid value, or when there
3629/// are no more variable arguments, is unsound.
3630///
3631#[rustc_intrinsic]
3632#[rustc_nounwind]
3633#[cfg(not(feature = "ferrocene_subset"))]
3634pub const unsafe fn va_arg<T: VaArgSafe>(ap: &mut VaList<'_>) -> T;
3635
3636/// Duplicates a variable argument list. The returned list is initially at the same position as
3637/// the one in `src`, but can be advanced independently.
3638///
3639/// Codegen backends should not have custom behavior for this intrinsic, they should always use
3640/// this fallback implementation. This intrinsic *does not* map to the LLVM `va_copy` intrinsic.
3641///
3642/// This intrinsic exists only as a hook for Miri and constant evaluation, and is used to detect UB
3643/// when a variable argument list is used incorrectly.
3644#[rustc_intrinsic]
3645#[rustc_nounwind]
3646#[cfg(not(feature = "ferrocene_subset"))]
3647pub const fn va_copy<'f>(src: &VaList<'f>) -> VaList<'f> {
3648    src.duplicate()
3649}
3650
3651/// Destroy the variable argument list `ap` after initialization with `va_start` (part of the
3652/// desugaring of `...`) or `va_copy`.
3653///
3654/// Code generation backends should not provide a custom implementation for this intrinsic. This
3655/// intrinsic *does not* map to the LLVM `va_end` intrinsic.
3656///
3657/// This function is a no-op on all current targets, but used as a hook for const evaluation to
3658/// detect UB when a variable argument list is used incorrectly.
3659///
3660/// # Safety
3661///
3662/// `ap` must not be used to access variable arguments after this call.
3663///
3664#[rustc_intrinsic]
3665#[rustc_nounwind]
3666#[cfg(not(feature = "ferrocene_subset"))]
3667pub const unsafe fn va_end(ap: &mut VaList<'_>) {
3668    /* deliberately does nothing */
3669}