From 99d57ee23d61293bc14f6a8f0eb9ad4fe10acc94 Mon Sep 17 00:00:00 2001 From: Arthur Cohen Date: Thu, 18 Aug 2022 11:15:26 +0200 Subject: [PATCH] core: Mark all safe intrinsics with #[rustc_safe_intrinsic] --- .../src/error_codes/E0094.md | 2 + .../src/error_codes/E0211.md | 2 + library/core/src/intrinsics.rs | 38 +++++++++++++++++++ src/test/ui/error-codes/E0094.rs | 2 + src/test/ui/error-codes/E0094.stderr | 2 +- src/test/ui/extern/extern-with-type-bounds.rs | 2 + .../ui/extern/extern-with-type-bounds.stderr | 2 +- src/test/ui/intrinsics/intrinsic-alignment.rs | 1 + src/test/ui/structs-enums/rec-align-u32.rs | 1 + src/test/ui/structs-enums/rec-align-u64.rs | 1 + 10 files changed, 51 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md index ec86ec44ece8e..cc546bdbb3b35 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0094.md +++ b/compiler/rustc_error_codes/src/error_codes/E0094.md @@ -6,6 +6,7 @@ Erroneous code example: #![feature(intrinsics)] extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of() -> usize; // error: intrinsic has wrong number // of type parameters } @@ -19,6 +20,7 @@ Example: #![feature(intrinsics)] extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of() -> usize; // ok! } ``` diff --git a/compiler/rustc_error_codes/src/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md index 77289f019005e..8c2462ebd9b86 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0211.md +++ b/compiler/rustc_error_codes/src/error_codes/E0211.md @@ -7,6 +7,7 @@ used. Erroneous code examples: #![feature(intrinsics)] extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of(); // error: intrinsic has wrong type } @@ -42,6 +43,7 @@ For the first code example, please check the function definition. Example: #![feature(intrinsics)] extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of() -> usize; // ok! } ``` diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs index 12b43da5a4280..15ee14398b676 100644 --- a/library/core/src/intrinsics.rs +++ b/library/core/src/intrinsics.rs @@ -788,6 +788,7 @@ extern "rust-intrinsic" { /// uninitialized at that point in the control flow. /// /// This intrinsic should not be used outside of the compiler. + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn rustc_peek(_: T) -> T; /// Aborts the execution of the process. @@ -805,6 +806,7 @@ extern "rust-intrinsic" { /// On Unix, the /// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or /// `SIGBUS`. The precise behaviour is not guaranteed and not stable. + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn abort() -> !; /// Informs the optimizer that this point in the code is not reachable, @@ -843,6 +845,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_likely", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn likely(b: bool) -> bool; /// Hints to the compiler that branch condition is likely to be false. @@ -857,6 +860,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_likely", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn unlikely(b: bool) -> bool; /// Executes a breakpoint trap, for inspection by a debugger. @@ -876,6 +880,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::mem::size_of`]. #[rustc_const_stable(feature = "const_size_of", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn size_of() -> usize; /// The minimum alignment of a type. @@ -887,6 +892,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::mem::align_of`]. #[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn min_align_of() -> usize; /// The preferred alignment of a type. /// @@ -915,6 +921,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::any::type_name`]. #[rustc_const_unstable(feature = "const_type_name", issue = "63084")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn type_name() -> &'static str; /// Gets an identifier which is globally unique to the specified type. This @@ -928,6 +935,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::any::TypeId::of`]. #[rustc_const_unstable(feature = "const_type_id", issue = "77125")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn type_id() -> u64; /// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited: @@ -935,6 +943,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_stable(feature = "const_assert_type", since = "1.59.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn assert_inhabited(); /// A guard for unsafe functions that cannot ever be executed if `T` does not permit @@ -942,6 +951,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_assert_type2", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn assert_zero_valid(); /// A guard for unsafe functions that cannot ever be executed if `T` has invalid @@ -949,6 +959,7 @@ extern "rust-intrinsic" { /// /// This intrinsic does not have a stable counterpart. #[rustc_const_unstable(feature = "const_assert_type2", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn assert_uninit_valid(); /// Gets a reference to a static `Location` indicating where it was called. @@ -960,6 +971,7 @@ extern "rust-intrinsic" { /// /// Consider using [`core::panic::Location::caller`] instead. #[rustc_const_unstable(feature = "const_caller_location", issue = "76156")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn caller_location() -> &'static crate::panic::Location<'static>; /// Moves a value out of scope without running drop glue. @@ -972,6 +984,7 @@ extern "rust-intrinsic" { /// Therefore, implementations must not require the user to uphold /// any safety invariants. #[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn forget(_: T); /// Reinterprets the bits of a value of one type as another type. @@ -1251,6 +1264,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop). #[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn needs_drop() -> bool; /// Calculates the offset from a pointer. @@ -1295,6 +1309,7 @@ extern "rust-intrinsic" { /// any safety invariants. /// /// Consider using [`pointer::mask`] instead. + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn ptr_mask(ptr: *const T, mask: usize) -> *const T; /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with @@ -1486,6 +1501,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f32::min`] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn minnumf32(x: f32, y: f32) -> f32; /// Returns the minimum of two `f64` values. /// @@ -1496,6 +1512,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f64::min`] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn minnumf64(x: f64, y: f64) -> f64; /// Returns the maximum of two `f32` values. /// @@ -1506,6 +1523,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f32::max`] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn maxnumf32(x: f32, y: f32) -> f32; /// Returns the maximum of two `f64` values. /// @@ -1516,6 +1534,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is /// [`f64::max`] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn maxnumf64(x: f64, y: f64) -> f64; /// Copies the sign from `y` to `x` for `f32` values. @@ -1636,6 +1655,7 @@ extern "rust-intrinsic" { /// primitives via the `count_ones` method. For example, /// [`u32::count_ones`] #[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn ctpop(x: T) -> T; /// Returns the number of leading unset bits (zeroes) in an integer type `T`. @@ -1673,6 +1693,7 @@ extern "rust-intrinsic" { /// assert_eq!(num_leading, 16); /// ``` #[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn ctlz(x: T) -> T; /// Like `ctlz`, but extra-unsafe as it returns `undef` when @@ -1729,6 +1750,7 @@ extern "rust-intrinsic" { /// assert_eq!(num_trailing, 16); /// ``` #[rustc_const_stable(feature = "const_cttz", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn cttz(x: T) -> T; /// Like `cttz`, but extra-unsafe as it returns `undef` when @@ -1761,6 +1783,7 @@ extern "rust-intrinsic" { /// primitives via the `swap_bytes` method. For example, /// [`u32::swap_bytes`] #[rustc_const_stable(feature = "const_bswap", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn bswap(x: T) -> T; /// Reverses the bits in an integer type `T`. @@ -1774,6 +1797,7 @@ extern "rust-intrinsic" { /// primitives via the `reverse_bits` method. For example, /// [`u32::reverse_bits`] #[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn bitreverse(x: T) -> T; /// Performs checked integer addition. @@ -1787,6 +1811,7 @@ extern "rust-intrinsic" { /// primitives via the `overflowing_add` method. For example, /// [`u32::overflowing_add`] #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn add_with_overflow(x: T, y: T) -> (T, bool); /// Performs checked integer subtraction @@ -1800,6 +1825,7 @@ extern "rust-intrinsic" { /// primitives via the `overflowing_sub` method. For example, /// [`u32::overflowing_sub`] #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn sub_with_overflow(x: T, y: T) -> (T, bool); /// Performs checked integer multiplication @@ -1813,6 +1839,7 @@ extern "rust-intrinsic" { /// primitives via the `overflowing_mul` method. For example, /// [`u32::overflowing_mul`] #[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn mul_with_overflow(x: T, y: T) -> (T, bool); /// Performs an exact division, resulting in undefined behavior where @@ -1887,6 +1914,7 @@ extern "rust-intrinsic" { /// primitives via the `rotate_left` method. For example, /// [`u32::rotate_left`] #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn rotate_left(x: T, y: T) -> T; /// Performs rotate right. @@ -1900,6 +1928,7 @@ extern "rust-intrinsic" { /// primitives via the `rotate_right` method. For example, /// [`u32::rotate_right`] #[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn rotate_right(x: T, y: T) -> T; /// Returns (a + b) mod 2N, where N is the width of T in bits. @@ -1913,6 +1942,7 @@ extern "rust-intrinsic" { /// primitives via the `wrapping_add` method. For example, /// [`u32::wrapping_add`] #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn wrapping_add(a: T, b: T) -> T; /// Returns (a - b) mod 2N, where N is the width of T in bits. /// @@ -1925,6 +1955,7 @@ extern "rust-intrinsic" { /// primitives via the `wrapping_sub` method. For example, /// [`u32::wrapping_sub`] #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn wrapping_sub(a: T, b: T) -> T; /// Returns (a * b) mod 2N, where N is the width of T in bits. /// @@ -1937,6 +1968,7 @@ extern "rust-intrinsic" { /// primitives via the `wrapping_mul` method. For example, /// [`u32::wrapping_mul`] #[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn wrapping_mul(a: T, b: T) -> T; /// Computes `a + b`, saturating at numeric bounds. @@ -1950,6 +1982,7 @@ extern "rust-intrinsic" { /// primitives via the `saturating_add` method. For example, /// [`u32::saturating_add`] #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn saturating_add(a: T, b: T) -> T; /// Computes `a - b`, saturating at numeric bounds. /// @@ -1962,6 +1995,7 @@ extern "rust-intrinsic" { /// primitives via the `saturating_sub` method. For example, /// [`u32::saturating_sub`] #[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn saturating_sub(a: T, b: T) -> T; /// Returns the value of the discriminant for the variant in 'v'; @@ -1974,6 +2008,7 @@ extern "rust-intrinsic" { /// /// The stabilized version of this intrinsic is [`core::mem::discriminant`]. #[rustc_const_unstable(feature = "const_discriminant", issue = "69821")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn discriminant_value(v: &T) -> ::Discriminant; /// Returns the number of variants of the type `T` cast to a `usize`; @@ -1986,6 +2021,7 @@ extern "rust-intrinsic" { /// /// The to-be-stabilized version of this intrinsic is [`mem::variant_count`]. #[rustc_const_unstable(feature = "variant_count", issue = "73662")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn variant_count() -> usize; /// Rust's "try catch" construct which invokes the function pointer `try_fn` @@ -2019,6 +2055,7 @@ extern "rust-intrinsic" { /// Therefore, implementations must not require the user to uphold /// any safety invariants. #[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn ptr_guaranteed_cmp(ptr: *const T, other: *const T) -> u8; /// Allocates a block of memory at compile time. @@ -2069,6 +2106,7 @@ extern "rust-intrinsic" { /// /// [`std::hint::black_box`]: crate::hint::black_box #[rustc_const_unstable(feature = "const_black_box", issue = "none")] + #[cfg_attr(not(bootstrap), rustc_safe_intrinsic)] pub fn black_box(dummy: T) -> T; /// `ptr` must point to a vtable. diff --git a/src/test/ui/error-codes/E0094.rs b/src/test/ui/error-codes/E0094.rs index 0d58e5a2862c4..a2ec932c12455 100644 --- a/src/test/ui/error-codes/E0094.rs +++ b/src/test/ui/error-codes/E0094.rs @@ -1,5 +1,7 @@ #![feature(intrinsics)] + extern "rust-intrinsic" { + #[rustc_safe_intrinsic] fn size_of() -> usize; //~ ERROR E0094 } diff --git a/src/test/ui/error-codes/E0094.stderr b/src/test/ui/error-codes/E0094.stderr index da97f3a014b06..531cd4c784d33 100644 --- a/src/test/ui/error-codes/E0094.stderr +++ b/src/test/ui/error-codes/E0094.stderr @@ -1,5 +1,5 @@ error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1 - --> $DIR/E0094.rs:3:15 + --> $DIR/E0094.rs:5:15 | LL | fn size_of() -> usize; | ^^^^^^ expected 1 type parameter diff --git a/src/test/ui/extern/extern-with-type-bounds.rs b/src/test/ui/extern/extern-with-type-bounds.rs index 8f9683e4a7485..a72aa4171a103 100644 --- a/src/test/ui/extern/extern-with-type-bounds.rs +++ b/src/test/ui/extern/extern-with-type-bounds.rs @@ -2,6 +2,7 @@ extern "rust-intrinsic" { // Real example from libcore + #[rustc_safe_intrinsic] fn type_id() -> u64; // Silent bounds made explicit to make sure they are actually @@ -10,6 +11,7 @@ extern "rust-intrinsic" { // Bounds aren't checked right now, so this should work // even though it's incorrect. + #[rustc_safe_intrinsic] fn size_of() -> usize; // Unresolved bounds should still error. diff --git a/src/test/ui/extern/extern-with-type-bounds.stderr b/src/test/ui/extern/extern-with-type-bounds.stderr index acd0596422f8a..88be1e5dd3da0 100644 --- a/src/test/ui/extern/extern-with-type-bounds.stderr +++ b/src/test/ui/extern/extern-with-type-bounds.stderr @@ -1,5 +1,5 @@ error[E0405]: cannot find trait `NoSuchTrait` in this scope - --> $DIR/extern-with-type-bounds.rs:16:20 + --> $DIR/extern-with-type-bounds.rs:18:20 | LL | fn align_of() -> usize; | ^^^^^^^^^^^ not found in this scope diff --git a/src/test/ui/intrinsics/intrinsic-alignment.rs b/src/test/ui/intrinsics/intrinsic-alignment.rs index 6007eba8c0906..c8b1ff1dbce3b 100644 --- a/src/test/ui/intrinsics/intrinsic-alignment.rs +++ b/src/test/ui/intrinsics/intrinsic-alignment.rs @@ -6,6 +6,7 @@ mod rusti { extern "rust-intrinsic" { pub fn pref_align_of() -> usize; + #[rustc_safe_intrinsic] pub fn min_align_of() -> usize; } } diff --git a/src/test/ui/structs-enums/rec-align-u32.rs b/src/test/ui/structs-enums/rec-align-u32.rs index 889294daa340c..ee704198d193b 100644 --- a/src/test/ui/structs-enums/rec-align-u32.rs +++ b/src/test/ui/structs-enums/rec-align-u32.rs @@ -10,6 +10,7 @@ use std::mem; mod rusti { extern "rust-intrinsic" { pub fn pref_align_of() -> usize; + #[rustc_safe_intrinsic] pub fn min_align_of() -> usize; } } diff --git a/src/test/ui/structs-enums/rec-align-u64.rs b/src/test/ui/structs-enums/rec-align-u64.rs index 3bc2d16cf9df2..40ede9705f115 100644 --- a/src/test/ui/structs-enums/rec-align-u64.rs +++ b/src/test/ui/structs-enums/rec-align-u64.rs @@ -12,6 +12,7 @@ use std::mem; mod rusti { extern "rust-intrinsic" { pub fn pref_align_of() -> usize; + #[rustc_safe_intrinsic] pub fn min_align_of() -> usize; } }