Module intrinsics

Compiler intrinsics.

The functions in this module are implementation details of core and should not be used outside of the standard library. We generally provide access to intrinsics via stable wrapper functions. Use these instead.

These are the imports making intrinsics available to Rust code. The actual implementations live in the compiler. 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. 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 and https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_codegen_llvm/src/intrinsic.rs, and for const evaluation in https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_const_eval/src/interpret/intrinsics.rs.

Intrinsics don't need a body. However, they optionally can have a body, which we call the "fallback body". This will be used by codegen backends that do not have a dedicated implementation of the intrinsic, making it easier to add new intrinsics for specific operations without having to implement them in each codegen backend. The fallback body obviously has to be a valid implementation of the documented specification of the intrinsic. In some cases, the fallback body will be equivalent to the specification. Note that this is a strong requirement: if the spec says "UB if input x is even", then a valid implementation can just ignore this and do whatever it wants in that case; an equivalent implementation needs to actually check this condition and trigger UB in that case (e.g. by using hint::assert_unchecked()). Similar, if the spec says "returns x or y non-deterministically", then an equivalent implementation must actually do non-deterministic choice and return either value (e.g. by invoking some other language operation that has the same non-determinism). Intrinsics with such a fallback body that is equivalent to the spec may be marked with #[miri::intrinsic_fallback_is_spec]; the fallback body will then also be used by Miri for UB checking. When in doubt, do not use this attribute or ask the Miri maintainers for advice.

Intrinsics are, in general, language extensions. Therefore, t-lang should be involved whenever a new intrinsic is exposed to stable code. However, if an intrinsic is marked #[miri::intrinsic_fallback_is_spec] with a fallback body that only uses stable features (or if such a fallback body could be written, but for one reason or another the actual fallback body is different), and if it also does not make other promises that go beyond observable program behavior (such as steering the optimizer in a particular direction), then an intrinsic may be used without t-lang involvement.

Const intrinsics

In order to make an intrinsic unstable usable at compile-time, copy the implementation from https://github.com/rust-lang/miri/blob/master/src/intrinsics to https://github.com/rust-lang/rust/blob/HEAD/compiler/rustc_const_eval/src/interpret/intrinsics.rs and make the intrinsic declaration below a const fn. This should be done in coordination with wg-const-eval.

If an intrinsic is supposed to be used from a const fn with a rustc_const_stable attribute, #[rustc_intrinsic_const_stable_indirect] needs to be added to the intrinsic. Such a change requires T-lang approval, because it may bake a feature into the language that cannot be replicated in user code without compiler support. The same exception as above applies for #[miri::intrinsic_fallback_is_spec] intrinsics.

Volatiles

The volatile intrinsics provide operations intended to act on I/O memory, which are guaranteed to not be reordered by the compiler across other volatile intrinsics. See [read_volatile][ptr::read_volatile] and [write_volatile][ptr::write_volatile].

Atomics

The atomic intrinsics provide common atomic operations on machine words, with multiple possible memory orderings. See the [atomic types][atomic] docs for details.

Unwinding

Rust intrinsics may, in general, unwind. If an intrinsic can never unwind, add the #[rustc_nounwind] attribute so that the compiler can make use of this fact.

However, even for intrinsics that may unwind, rustc assumes that a Rust intrinsics will never initiate a foreign (non-Rust) unwind, and thus for panic=abort we can always assume that these intrinsics cannot unwind.

Modules

Enums

Functions

Macros