diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs index 2316fc4318918..5596ef029bcc8 100644 --- a/library/core/src/intrinsics/mod.rs +++ b/library/core/src/intrinsics/mod.rs @@ -10,6 +10,30 @@ //! and , //! and for const evaluation in . //! +//! 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 @@ -19,9 +43,10 @@ //! 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. +//! `#[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 //!