11//! Compiler intrinsics.
22//!
33//! The corresponding definitions are in `librustc_codegen_llvm/intrinsic.rs`.
4+ //! The corresponding const implementations are in `librustc_mir/interpret/intrinsics.rs`
5+ //!
6+ //! # Const intrinsics
7+ //!
8+ //! Note: any changes to the constness of intrinsics should be discussed with the language team.
9+ //! This includes changes in the stability of the constness.
10+ //!
11+ //! In order to make an intrinsic usable at compile-time, one needs to copy the implementation
12+ //! from https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs to
13+ //! `librustc_mir/interpret/intrinsics.rs` and add a
14+ //! `#[rustc_const_unstable(feature = "foo", issue = "01234")]` to the intrinsic.
15+ //!
16+ //! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
17+ //! the intrinsic's attribute must be `rustc_const_stable`, too. Such a change should not be done
18+ //! without T-lang consulation, because it bakes a feature into the language that cannot be
19+ //! replicated in user code without compiler support.
420//!
521//! # Volatiles
622//!
@@ -671,14 +687,17 @@ extern "rust-intrinsic" {
671687 ///
672688 /// The stabilized version of this intrinsic is
673689 /// [`std::mem::size_of`](../../std/mem/fn.size_of.html).
690+ #[ rustc_const_stable( feature = "const_size_of" , since = "1.40.0" ) ]
674691 pub fn size_of < T > ( ) -> usize ;
675692
676693 /// Moves a value to an uninitialized memory location.
677694 ///
678695 /// Drop glue is not run on the destination.
679696 pub fn move_val_init < T > ( dst : * mut T , src : T ) ;
680697
698+ #[ rustc_const_stable( feature = "const_min_align_of" , since = "1.40.0" ) ]
681699 pub fn min_align_of < T > ( ) -> usize ;
700+ #[ rustc_const_unstable( feature = "const_pref_align_of" , issue = "0" ) ]
682701 pub fn pref_align_of < T > ( ) -> usize ;
683702
684703 /// The size of the referenced value in bytes.
@@ -689,18 +708,21 @@ extern "rust-intrinsic" {
689708 pub fn min_align_of_val < T : ?Sized > ( _: & T ) -> usize ;
690709
691710 /// Gets a static string slice containing the name of a type.
711+ #[ rustc_const_unstable( feature = "const_type_name" , issue = "0" ) ]
692712 pub fn type_name < T : ?Sized > ( ) -> & ' static str ;
693713
694714 /// Gets an identifier which is globally unique to the specified type. This
695715 /// function will return the same value for a type regardless of whichever
696716 /// crate it is invoked in.
717+ #[ rustc_const_unstable( feature = "const_type_id" , issue = "0" ) ]
697718 pub fn type_id < T : ?Sized + ' static > ( ) -> u64 ;
698719
699720 /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
700721 /// This will statically either panic, or do nothing.
701722 pub fn panic_if_uninhabited < T > ( ) ;
702723
703724 /// Gets a reference to a static `Location` indicating where it was called.
725+ #[ rustc_const_unstable( feature = "const_caller_location" , issue = "47809" ) ]
704726 pub fn caller_location ( ) -> & ' static crate :: panic:: Location < ' static > ;
705727
706728 /// Creates a value initialized to zero.
@@ -957,6 +979,7 @@ extern "rust-intrinsic" {
957979 ///
958980 /// The stabilized version of this intrinsic is
959981 /// [`std::mem::needs_drop`](../../std/mem/fn.needs_drop.html).
982+ #[ rustc_const_stable( feature = "const_needs_drop" , since = "1.40.0" ) ]
960983 pub fn needs_drop < T > ( ) -> bool ;
961984
962985 /// Calculates the offset from a pointer.
@@ -1154,6 +1177,7 @@ extern "rust-intrinsic" {
11541177 pub fn float_to_int_approx_unchecked < Float , Int > ( value : Float ) -> Int ;
11551178
11561179 /// Returns the number of bits set in an integer type `T`
1180+ #[ rustc_const_stable( feature = "const_ctpop" , since = "1.40.0" ) ]
11571181 pub fn ctpop < T > ( x : T ) -> T ;
11581182
11591183 /// Returns the number of leading unset bits (zeroes) in an integer type `T`.
@@ -1181,6 +1205,7 @@ extern "rust-intrinsic" {
11811205 /// let num_leading = ctlz(x);
11821206 /// assert_eq!(num_leading, 16);
11831207 /// ```
1208+ #[ rustc_const_stable( feature = "const_ctlz" , since = "1.40.0" ) ]
11841209 pub fn ctlz < T > ( x : T ) -> T ;
11851210
11861211 /// Like `ctlz`, but extra-unsafe as it returns `undef` when
@@ -1197,6 +1222,7 @@ extern "rust-intrinsic" {
11971222 /// let num_leading = unsafe { ctlz_nonzero(x) };
11981223 /// assert_eq!(num_leading, 3);
11991224 /// ```
1225+ #[ rustc_const_unstable( feature = "constctlz" , issue = "0" ) ]
12001226 pub fn ctlz_nonzero < T > ( x : T ) -> T ;
12011227
12021228 /// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
@@ -1224,6 +1250,7 @@ extern "rust-intrinsic" {
12241250 /// let num_trailing = cttz(x);
12251251 /// assert_eq!(num_trailing, 16);
12261252 /// ```
1253+ #[ rustc_const_stable( feature = "const_cttz" , since = "1.40.0" ) ]
12271254 pub fn cttz < T > ( x : T ) -> T ;
12281255
12291256 /// Like `cttz`, but extra-unsafe as it returns `undef` when
@@ -1240,30 +1267,36 @@ extern "rust-intrinsic" {
12401267 /// let num_trailing = unsafe { cttz_nonzero(x) };
12411268 /// assert_eq!(num_trailing, 3);
12421269 /// ```
1270+ #[ rustc_const_unstable( feature = "const_cttz" , issue = "0" ) ]
12431271 pub fn cttz_nonzero < T > ( x : T ) -> T ;
12441272
12451273 /// Reverses the bytes in an integer type `T`.
1274+ #[ rustc_const_stable( feature = "const_bswap" , since = "1.40.0" ) ]
12461275 pub fn bswap < T > ( x : T ) -> T ;
12471276
12481277 /// Reverses the bits in an integer type `T`.
1278+ #[ rustc_const_stable( feature = "const_bitreverse" , since = "1.40.0" ) ]
12491279 pub fn bitreverse < T > ( x : T ) -> T ;
12501280
12511281 /// Performs checked integer addition.
12521282 /// The stabilized versions of this intrinsic are available on the integer
12531283 /// primitives via the `overflowing_add` method. For example,
12541284 /// [`std::u32::overflowing_add`](../../std/primitive.u32.html#method.overflowing_add)
1285+ #[ rustc_const_stable( feature = "const_int_overflow" , since = "1.40.0" ) ]
12551286 pub fn add_with_overflow < T > ( x : T , y : T ) -> ( T , bool ) ;
12561287
12571288 /// Performs checked integer subtraction
12581289 /// The stabilized versions of this intrinsic are available on the integer
12591290 /// primitives via the `overflowing_sub` method. For example,
12601291 /// [`std::u32::overflowing_sub`](../../std/primitive.u32.html#method.overflowing_sub)
1292+ #[ rustc_const_stable( feature = "const_int_overflow" , since = "1.40.0" ) ]
12611293 pub fn sub_with_overflow < T > ( x : T , y : T ) -> ( T , bool ) ;
12621294
12631295 /// Performs checked integer multiplication
12641296 /// The stabilized versions of this intrinsic are available on the integer
12651297 /// primitives via the `overflowing_mul` method. For example,
12661298 /// [`std::u32::overflowing_mul`](../../std/primitive.u32.html#method.overflowing_mul)
1299+ #[ rustc_const_stable( feature = "const_int_overflow" , since = "1.40.0" ) ]
12671300 pub fn mul_with_overflow < T > ( x : T , y : T ) -> ( T , bool ) ;
12681301
12691302 /// Performs an exact division, resulting in undefined behavior where
@@ -1279,9 +1312,11 @@ extern "rust-intrinsic" {
12791312
12801313 /// Performs an unchecked left shift, resulting in undefined behavior when
12811314 /// y < 0 or y >= N, where N is the width of T in bits.
1315+ #[ rustc_const_stable( feature = "const_int_unchecked" , since = "1.40.0" ) ]
12821316 pub fn unchecked_shl < T > ( x : T , y : T ) -> T ;
12831317 /// Performs an unchecked right shift, resulting in undefined behavior when
12841318 /// y < 0 or y >= N, where N is the width of T in bits.
1319+ #[ rustc_const_stable( feature = "const_int_unchecked" , since = "1.40.0" ) ]
12851320 pub fn unchecked_shr < T > ( x : T , y : T ) -> T ;
12861321
12871322 /// Returns the result of an unchecked addition, resulting in
@@ -1300,39 +1335,46 @@ extern "rust-intrinsic" {
13001335 /// The stabilized versions of this intrinsic are available on the integer
13011336 /// primitives via the `rotate_left` method. For example,
13021337 /// [`std::u32::rotate_left`](../../std/primitive.u32.html#method.rotate_left)
1338+ #[ rustc_const_stable( feature = "const_int_rotate" , since = "1.40.0" ) ]
13031339 pub fn rotate_left < T > ( x : T , y : T ) -> T ;
13041340
13051341 /// Performs rotate right.
13061342 /// The stabilized versions of this intrinsic are available on the integer
13071343 /// primitives via the `rotate_right` method. For example,
13081344 /// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right)
1345+ #[ rustc_const_stable( feature = "const_int_rotate" , since = "1.40.0" ) ]
13091346 pub fn rotate_right < T > ( x : T , y : T ) -> T ;
13101347
13111348 /// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
13121349 /// The stabilized versions of this intrinsic are available on the integer
13131350 /// primitives via the `wrapping_add` method. For example,
13141351 /// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
1352+ #[ rustc_const_stable( feature = "const_int_wrapping" , since = "1.40.0" ) ]
13151353 pub fn wrapping_add < T > ( a : T , b : T ) -> T ;
13161354 /// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
13171355 /// The stabilized versions of this intrinsic are available on the integer
13181356 /// primitives via the `wrapping_sub` method. For example,
13191357 /// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
1358+ #[ rustc_const_stable( feature = "const_int_wrapping" , since = "1.40.0" ) ]
13201359 pub fn wrapping_sub < T > ( a : T , b : T ) -> T ;
13211360 /// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
13221361 /// The stabilized versions of this intrinsic are available on the integer
13231362 /// primitives via the `wrapping_mul` method. For example,
13241363 /// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
1364+ #[ rustc_const_stable( feature = "const_int_wrapping" , since = "1.40.0" ) ]
13251365 pub fn wrapping_mul < T > ( a : T , b : T ) -> T ;
13261366
13271367 /// Computes `a + b`, while saturating at numeric bounds.
13281368 /// The stabilized versions of this intrinsic are available on the integer
13291369 /// primitives via the `saturating_add` method. For example,
13301370 /// [`std::u32::saturating_add`](../../std/primitive.u32.html#method.saturating_add)
1371+ #[ rustc_const_stable( feature = "const_int_saturating" , since = "1.40.0" ) ]
13311372 pub fn saturating_add < T > ( a : T , b : T ) -> T ;
13321373 /// Computes `a - b`, while saturating at numeric bounds.
13331374 /// The stabilized versions of this intrinsic are available on the integer
13341375 /// primitives via the `saturating_sub` method. For example,
13351376 /// [`std::u32::saturating_sub`](../../std/primitive.u32.html#method.saturating_sub)
1377+ #[ rustc_const_stable( feature = "const_int_saturating" , since = "1.40.0" ) ]
13361378 pub fn saturating_sub < T > ( a : T , b : T ) -> T ;
13371379
13381380 /// Returns the value of the discriminant for the variant in 'v',
@@ -1354,6 +1396,7 @@ extern "rust-intrinsic" {
13541396 pub fn nontemporal_store < T > ( ptr : * mut T , val : T ) ;
13551397
13561398 /// See documentation of `<*const T>::offset_from` for details.
1399+ #[ rustc_const_unstable( feature = "const_ptr_offset_from" , issue = "0" ) ]
13571400 pub fn ptr_offset_from < T > ( ptr : * const T , base : * const T ) -> isize ;
13581401
13591402 /// Internal hook used by Miri to implement unwinding.
0 commit comments