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