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