Skip to content

Commit 9ee16e1

Browse files
committedDec 20, 2019
Require const stability attributes on intrinsics to be able to use them in constant contexts
1 parent 01a4650 commit 9ee16e1

File tree

6 files changed

+38
-97
lines changed

6 files changed

+38
-97
lines changed
 

‎src/libcore/intrinsics.rs

+28-1
Original file line numberDiff line numberDiff line change
@@ -667,14 +667,17 @@ extern "rust-intrinsic" {
667667
///
668668
/// The stabilized version of this intrinsic is
669669
/// [`std::mem::size_of`](../../std/mem/fn.size_of.html).
670+
#[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
670671
pub fn size_of<T>() -> usize;
671672

672673
/// Moves a value to an uninitialized memory location.
673674
///
674675
/// Drop glue is not run on the destination.
675676
pub fn move_val_init<T>(dst: *mut T, src: T);
676677

678+
#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
677679
pub fn min_align_of<T>() -> usize;
680+
#[rustc_const_unstable(feature = "const_pref_align_of", issue = "0")]
678681
pub fn pref_align_of<T>() -> usize;
679682

680683
/// The size of the referenced value in bytes.
@@ -685,18 +688,21 @@ extern "rust-intrinsic" {
685688
pub fn min_align_of_val<T: ?Sized>(_: &T) -> usize;
686689

687690
/// Gets a static string slice containing the name of a type.
691+
#[rustc_const_unstable(feature = "const_type_name", issue = "0")]
688692
pub fn type_name<T: ?Sized>() -> &'static str;
689693

690694
/// Gets an identifier which is globally unique to the specified type. This
691695
/// function will return the same value for a type regardless of whichever
692696
/// crate it is invoked in.
697+
#[rustc_const_unstable(feature = "const_type_id", issue = "0")]
693698
pub fn type_id<T: ?Sized + 'static>() -> u64;
694699

695700
/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
696701
/// This will statically either panic, or do nothing.
697702
pub fn panic_if_uninhabited<T>();
698703

699704
/// Gets a reference to a static `Location` indicating where it was called.
705+
#[rustc_const_unstable(feature = "const_caller_location", issue = "47809")]
700706
pub fn caller_location() -> &'static crate::panic::Location<'static>;
701707

702708
/// Creates a value initialized to zero.
@@ -951,6 +957,7 @@ extern "rust-intrinsic" {
951957
///
952958
/// The stabilized version of this intrinsic is
953959
/// [`std::mem::needs_drop`](../../std/mem/fn.needs_drop.html).
960+
#[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")]
954961
pub fn needs_drop<T>() -> bool;
955962

956963
/// Calculates the offset from a pointer.
@@ -1150,6 +1157,7 @@ extern "rust-intrinsic" {
11501157

11511158

11521159
/// Returns the number of bits set in an integer type `T`
1160+
#[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")]
11531161
pub fn ctpop<T>(x: T) -> T;
11541162

11551163
/// Returns the number of leading unset bits (zeroes) in an integer type `T`.
@@ -1177,6 +1185,7 @@ extern "rust-intrinsic" {
11771185
/// let num_leading = ctlz(x);
11781186
/// assert_eq!(num_leading, 16);
11791187
/// ```
1188+
#[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")]
11801189
pub fn ctlz<T>(x: T) -> T;
11811190

11821191
/// Like `ctlz`, but extra-unsafe as it returns `undef` when
@@ -1193,6 +1202,7 @@ extern "rust-intrinsic" {
11931202
/// let num_leading = unsafe { ctlz_nonzero(x) };
11941203
/// assert_eq!(num_leading, 3);
11951204
/// ```
1205+
#[rustc_const_unstable(feature = "constctlz", issue = "0")]
11961206
pub fn ctlz_nonzero<T>(x: T) -> T;
11971207

11981208
/// Returns the number of trailing unset bits (zeroes) in an integer type `T`.
@@ -1220,6 +1230,7 @@ extern "rust-intrinsic" {
12201230
/// let num_trailing = cttz(x);
12211231
/// assert_eq!(num_trailing, 16);
12221232
/// ```
1233+
#[rustc_const_stable(feature = "const_cttz", since = "1.40.0")]
12231234
pub fn cttz<T>(x: T) -> T;
12241235

12251236
/// Like `cttz`, but extra-unsafe as it returns `undef` when
@@ -1236,30 +1247,36 @@ extern "rust-intrinsic" {
12361247
/// let num_trailing = unsafe { cttz_nonzero(x) };
12371248
/// assert_eq!(num_trailing, 3);
12381249
/// ```
1250+
#[rustc_const_unstable(feature = "const_cttz", issue = "0")]
12391251
pub fn cttz_nonzero<T>(x: T) -> T;
12401252

12411253
/// Reverses the bytes in an integer type `T`.
1254+
#[rustc_const_stable(feature = "const_bswap", since = "1.40.0")]
12421255
pub fn bswap<T>(x: T) -> T;
12431256

12441257
/// Reverses the bits in an integer type `T`.
1258+
#[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")]
12451259
pub fn bitreverse<T>(x: T) -> T;
12461260

12471261
/// Performs checked integer addition.
12481262
/// The stabilized versions of this intrinsic are available on the integer
12491263
/// primitives via the `overflowing_add` method. For example,
12501264
/// [`std::u32::overflowing_add`](../../std/primitive.u32.html#method.overflowing_add)
1265+
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
12511266
pub fn add_with_overflow<T>(x: T, y: T) -> (T, bool);
12521267

12531268
/// Performs checked integer subtraction
12541269
/// The stabilized versions of this intrinsic are available on the integer
12551270
/// primitives via the `overflowing_sub` method. For example,
12561271
/// [`std::u32::overflowing_sub`](../../std/primitive.u32.html#method.overflowing_sub)
1272+
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
12571273
pub fn sub_with_overflow<T>(x: T, y: T) -> (T, bool);
12581274

12591275
/// Performs checked integer multiplication
12601276
/// The stabilized versions of this intrinsic are available on the integer
12611277
/// primitives via the `overflowing_mul` method. For example,
12621278
/// [`std::u32::overflowing_mul`](../../std/primitive.u32.html#method.overflowing_mul)
1279+
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
12631280
pub fn mul_with_overflow<T>(x: T, y: T) -> (T, bool);
12641281

12651282
/// Performs an exact division, resulting in undefined behavior where
@@ -1275,9 +1292,11 @@ extern "rust-intrinsic" {
12751292

12761293
/// Performs an unchecked left shift, resulting in undefined behavior when
12771294
/// y < 0 or y >= N, where N is the width of T in bits.
1295+
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
12781296
pub fn unchecked_shl<T>(x: T, y: T) -> T;
12791297
/// Performs an unchecked right shift, resulting in undefined behavior when
12801298
/// y < 0 or y >= N, where N is the width of T in bits.
1299+
#[rustc_const_stable(feature = "const_int_unchecked", since = "1.40.0")]
12811300
pub fn unchecked_shr<T>(x: T, y: T) -> T;
12821301

12831302
/// Returns the result of an unchecked addition, resulting in
@@ -1296,39 +1315,46 @@ extern "rust-intrinsic" {
12961315
/// The stabilized versions of this intrinsic are available on the integer
12971316
/// primitives via the `rotate_left` method. For example,
12981317
/// [`std::u32::rotate_left`](../../std/primitive.u32.html#method.rotate_left)
1318+
#[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
12991319
pub fn rotate_left<T>(x: T, y: T) -> T;
13001320

13011321
/// Performs rotate right.
13021322
/// The stabilized versions of this intrinsic are available on the integer
13031323
/// primitives via the `rotate_right` method. For example,
1304-
/// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right)
1324+
/// [`std::u32::rotate_right`](../../std/primitive.u32.html#method.rotate_right
1325+
#[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
13051326
pub fn rotate_right<T>(x: T, y: T) -> T;
13061327

13071328
/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
13081329
/// The stabilized versions of this intrinsic are available on the integer
13091330
/// primitives via the `wrapping_add` method. For example,
13101331
/// [`std::u32::wrapping_add`](../../std/primitive.u32.html#method.wrapping_add)
1332+
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
13111333
pub fn wrapping_add<T>(a: T, b: T) -> T;
13121334
/// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
13131335
/// The stabilized versions of this intrinsic are available on the integer
13141336
/// primitives via the `wrapping_sub` method. For example,
13151337
/// [`std::u32::wrapping_sub`](../../std/primitive.u32.html#method.wrapping_sub)
1338+
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
13161339
pub fn wrapping_sub<T>(a: T, b: T) -> T;
13171340
/// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
13181341
/// The stabilized versions of this intrinsic are available on the integer
13191342
/// primitives via the `wrapping_mul` method. For example,
13201343
/// [`std::u32::wrapping_mul`](../../std/primitive.u32.html#method.wrapping_mul)
1344+
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
13211345
pub fn wrapping_mul<T>(a: T, b: T) -> T;
13221346

13231347
/// Computes `a + b`, while saturating at numeric bounds.
13241348
/// The stabilized versions of this intrinsic are available on the integer
13251349
/// primitives via the `saturating_add` method. For example,
13261350
/// [`std::u32::saturating_add`](../../std/primitive.u32.html#method.saturating_add)
1351+
#[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
13271352
pub fn saturating_add<T>(a: T, b: T) -> T;
13281353
/// Computes `a - b`, while saturating at numeric bounds.
13291354
/// The stabilized versions of this intrinsic are available on the integer
13301355
/// primitives via the `saturating_sub` method. For example,
13311356
/// [`std::u32::saturating_sub`](../../std/primitive.u32.html#method.saturating_sub)
1357+
#[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
13321358
pub fn saturating_sub<T>(a: T, b: T) -> T;
13331359

13341360
/// Returns the value of the discriminant for the variant in 'v',
@@ -1350,6 +1376,7 @@ extern "rust-intrinsic" {
13501376
pub fn nontemporal_store<T>(ptr: *mut T, val: T);
13511377

13521378
/// See documentation of `<*const T>::offset_from` for details.
1379+
#[rustc_const_unstable(feature = "const_ptr_offset_from", issue = "0")]
13531380
pub fn ptr_offset_from<T>(ptr: *const T, base: *const T) -> isize;
13541381

13551382
/// Internal hook used by Miri to implement unwinding.

‎src/libcore/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@
128128
#![feature(maybe_uninit_slice)]
129129
#![feature(external_doc)]
130130
#![feature(associated_type_bounds)]
131+
#![feature(const_type_id)]
132+
#![feature(const_caller_location)]
131133

132134
#[prelude_import]
133135
#[allow(unused)]

‎src/libcore/macros/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// the `caller_location` intrinsic, but once `#[track_caller]` is implemented,
66
// `panicking::{panic, panic_fmt}` can use that instead of a `Location` argument.
77
core_intrinsics,
8+
const_caller_location,
89
)]
910
#[stable(feature = "core", since = "1.6.0")]
1011
macro_rules! panic {

‎src/librustc/ty/constness.rs

+2-96
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::ty::query::Providers;
22
use crate::hir::def_id::DefId;
33
use crate::hir;
44
use crate::ty::TyCtxt;
5-
use syntax_pos::symbol::{sym, Symbol};
5+
use syntax_pos::symbol::Symbol;
66
use rustc_target::spec::abi::Abi;
77
use crate::hir::map::blocks::FnLikeNode;
88
use syntax::attr;
@@ -41,51 +41,12 @@ impl<'tcx> TyCtxt<'tcx> {
4141
}
4242
}
4343

44-
/// Returns `true` if the `def_id` refers to an intrisic which we've whitelisted
45-
/// for being called from stable `const fn`s (`min_const_fn`).
46-
///
47-
/// Adding more intrinsics requires sign-off from @rust-lang/lang.
48-
///
49-
/// This list differs from the list in `is_const_intrinsic` in the sense that any item on this
50-
/// list must be on the `is_const_intrinsic` list, too, because if an intrinsic is callable from
51-
/// stable, it must be callable at all.
52-
fn is_intrinsic_min_const_fn(self, def_id: DefId) -> bool {
53-
match self.item_name(def_id) {
54-
| sym::size_of
55-
| sym::min_align_of
56-
| sym::needs_drop
57-
// Arithmetic:
58-
| sym::add_with_overflow // ~> .overflowing_add
59-
| sym::sub_with_overflow // ~> .overflowing_sub
60-
| sym::mul_with_overflow // ~> .overflowing_mul
61-
| sym::wrapping_add // ~> .wrapping_add
62-
| sym::wrapping_sub // ~> .wrapping_sub
63-
| sym::wrapping_mul // ~> .wrapping_mul
64-
| sym::saturating_add // ~> .saturating_add
65-
| sym::saturating_sub // ~> .saturating_sub
66-
| sym::unchecked_shl // ~> .wrapping_shl
67-
| sym::unchecked_shr // ~> .wrapping_shr
68-
| sym::rotate_left // ~> .rotate_left
69-
| sym::rotate_right // ~> .rotate_right
70-
| sym::ctpop // ~> .count_ones
71-
| sym::ctlz // ~> .leading_zeros
72-
| sym::cttz // ~> .trailing_zeros
73-
| sym::bswap // ~> .swap_bytes
74-
| sym::bitreverse // ~> .reverse_bits
75-
=> true,
76-
_ => false,
77-
}
78-
}
79-
8044
/// Returns `true` if this function must conform to `min_const_fn`
8145
pub fn is_min_const_fn(self, def_id: DefId) -> bool {
8246
// Bail out if the signature doesn't contain `const`
8347
if !self.is_const_fn_raw(def_id) {
8448
return false;
8549
}
86-
if let Abi::RustIntrinsic = self.fn_sig(def_id).abi() {
87-
return self.is_intrinsic_min_const_fn(def_id);
88-
}
8950

9051
if self.features().staged_api {
9152
// In order for a libstd function to be considered min_const_fn
@@ -134,62 +95,7 @@ pub fn provide(providers: &mut Providers<'_>) {
13495
fn is_const_intrinsic(tcx: TyCtxt<'_>, def_id: DefId) -> Option<bool> {
13596
match tcx.fn_sig(def_id).abi() {
13697
Abi::RustIntrinsic |
137-
Abi::PlatformIntrinsic => {
138-
// FIXME: deduplicate these two lists as much as possible
139-
match tcx.item_name(def_id) {
140-
// Keep this list in the same order as the match patterns in
141-
// `librustc_mir/interpret/intrinsics.rs`
142-
143-
// This whitelist is a list of intrinsics that have a miri-engine implementation
144-
// and can thus be called when enabling enough feature gates. The similar
145-
// whitelist in `is_intrinsic_min_const_fn` (in this file), exists for allowing
146-
// the intrinsics to be called by stable const fns.
147-
| sym::caller_location
148-
149-
| sym::min_align_of
150-
| sym::pref_align_of
151-
| sym::needs_drop
152-
| sym::size_of
153-
| sym::type_id
154-
| sym::type_name
155-
156-
| sym::ctpop
157-
| sym::cttz
158-
| sym::cttz_nonzero
159-
| sym::ctlz
160-
| sym::ctlz_nonzero
161-
| sym::bswap
162-
| sym::bitreverse
163-
164-
| sym::wrapping_add
165-
| sym::wrapping_sub
166-
| sym::wrapping_mul
167-
| sym::add_with_overflow
168-
| sym::sub_with_overflow
169-
| sym::mul_with_overflow
170-
171-
| sym::saturating_add
172-
| sym::saturating_sub
173-
174-
| sym::unchecked_shl
175-
| sym::unchecked_shr
176-
177-
| sym::rotate_left
178-
| sym::rotate_right
179-
180-
| sym::ptr_offset_from
181-
182-
| sym::transmute
183-
184-
| sym::simd_insert
185-
186-
| sym::simd_extract
187-
188-
=> Some(true),
189-
190-
_ => Some(false)
191-
}
192-
}
98+
Abi::PlatformIntrinsic => Some(tcx.lookup_const_stability(def_id).is_some()),
19399
_ => None
194100
}
195101
}

‎src/test/ui/consts/const-eval/simd/insert_extract.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22
#![feature(const_fn)]
33
#![feature(repr_simd)]
44
#![feature(platform_intrinsics)]
5+
#![feature(staged_api)]
6+
#![stable(feature = "foo", since = "1.33.7")]
57
#![allow(non_camel_case_types)]
68

79
#[repr(simd)] struct i8x1(i8);
810
#[repr(simd)] struct u16x2(u16, u16);
911
#[repr(simd)] struct f32x3(f32, f32, f32);
1012

1113
extern "platform-intrinsic" {
14+
#[rustc_const_stable(feature = "foo", since = "1.3.37")]
1215
fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
16+
#[rustc_const_stable(feature = "foo", since = "1.3.37")]
1317
fn simd_extract<T, U>(x: T, idx: u32) -> U;
1418
}
1519

‎src/test/ui/consts/const-fn-type-name.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#![feature(core_intrinsics)]
44
#![feature(const_fn)]
5+
#![feature(const_type_name)]
56
#![allow(dead_code)]
67

78
const fn type_name_wrapper<T>(_: &T) -> &'static str {

0 commit comments

Comments
 (0)
Please sign in to comment.