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