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