Skip to content

Commit ce7f0f1

Browse files
committedSep 28, 2022
Auto merge of #100719 - CohenArthur:rust-safe-intrinsic-attribute, r=wesleywiser
Add `#[rustc_safe_intrinsic]` This PR adds the `#[rustc_safe_intrinsic]` attribute as mentionned on Zulip. The goal of this attribute is to avoid keeping a list of symbols as the source for stable intrinsics, and instead rely on an attribute. This is similar to `#[rustc_const_stable]` and `#[rustc_const_unstable]`, which among other things, are used to mark the constness of intrinsic functions.
2 parents 307dd93 + b1b8649 commit ce7f0f1

File tree

21 files changed

+113
-10
lines changed

21 files changed

+113
-10
lines changed
 

‎compiler/rustc_error_codes/src/error_codes/E0094.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Erroneous code example:
66
#![feature(intrinsics)]
77
88
extern "rust-intrinsic" {
9+
#[rustc_safe_intrinsic]
910
fn size_of<T, U>() -> usize; // error: intrinsic has wrong number
1011
// of type parameters
1112
}
@@ -19,6 +20,7 @@ Example:
1920
#![feature(intrinsics)]
2021
2122
extern "rust-intrinsic" {
23+
#[rustc_safe_intrinsic]
2224
fn size_of<T>() -> usize; // ok!
2325
}
2426
```

‎compiler/rustc_error_codes/src/error_codes/E0211.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ used. Erroneous code examples:
77
#![feature(intrinsics)]
88
99
extern "rust-intrinsic" {
10+
#[rustc_safe_intrinsic]
1011
fn size_of<T>(); // error: intrinsic has wrong type
1112
}
1213
@@ -42,6 +43,7 @@ For the first code example, please check the function definition. Example:
4243
#![feature(intrinsics)]
4344
4445
extern "rust-intrinsic" {
46+
#[rustc_safe_intrinsic]
4547
fn size_of<T>() -> usize; // ok!
4648
}
4749
```

‎compiler/rustc_feature/src/builtin_attrs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
499499
),
500500
ungated!(rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
501501
ungated!(rustc_const_stable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
502+
ungated!(rustc_safe_intrinsic, Normal, template!(Word), DuplicatesOk),
502503
ungated!(
503504
rustc_default_body_unstable, Normal,
504505
template!(List: r#"feature = "name", reason = "...", issue = "N""#), DuplicatesOk

‎compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use crate::errors::{
77
};
88
use crate::require_same_types;
99

10-
use rustc_errors::struct_span_err;
10+
use hir::def_id::DefId;
11+
use rustc_errors::{struct_span_err, DiagnosticMessage};
1112
use rustc_hir as hir;
1213
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
1314
use rustc_middle::ty::{self, TyCtxt};
@@ -61,8 +62,12 @@ fn equate_intrinsic_type<'tcx>(
6162
}
6263

6364
/// Returns the unsafety of the given intrinsic.
64-
pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
65-
match intrinsic {
65+
pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir::Unsafety {
66+
let has_safe_attr = match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
67+
true => hir::Unsafety::Normal,
68+
false => hir::Unsafety::Unsafe,
69+
};
70+
let is_in_list = match tcx.item_name(intrinsic_id) {
6671
// When adding a new intrinsic to this list,
6772
// it's usually worth updating that intrinsic's documentation
6873
// to note that it's safe to call, since
@@ -106,14 +111,26 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
106111
| sym::variant_count
107112
| sym::ptr_mask => hir::Unsafety::Normal,
108113
_ => hir::Unsafety::Unsafe,
114+
};
115+
116+
if has_safe_attr != is_in_list {
117+
tcx.sess.struct_span_err(
118+
tcx.def_span(intrinsic_id),
119+
DiagnosticMessage::Str(format!(
120+
"intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `{}`",
121+
tcx.item_name(intrinsic_id)
122+
))).emit();
109123
}
124+
125+
is_in_list
110126
}
111127

112128
/// Remember to add all intrinsics here, in `compiler/rustc_codegen_llvm/src/intrinsic.rs`,
113129
/// and in `library/core/src/intrinsics.rs`.
114130
pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
115131
let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
116-
let intrinsic_name = tcx.item_name(it.def_id.to_def_id());
132+
let intrinsic_id = it.def_id.to_def_id();
133+
let intrinsic_name = tcx.item_name(intrinsic_id);
117134
let name_str = intrinsic_name.as_str();
118135

119136
let bound_vars = tcx.mk_bound_variable_kinds(
@@ -160,7 +177,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
160177
};
161178
(n_tps, 0, inputs, output, hir::Unsafety::Unsafe)
162179
} else {
163-
let unsafety = intrinsic_operation_unsafety(intrinsic_name);
180+
let unsafety = intrinsic_operation_unsafety(tcx, intrinsic_id);
164181
let (n_tps, inputs, output) = match intrinsic_name {
165182
sym::abort => (0, Vec::new(), tcx.types.never),
166183
sym::unreachable => (0, Vec::new(), tcx.types.never),

‎compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2544,7 +2544,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
25442544
abi: abi::Abi,
25452545
) -> ty::PolyFnSig<'tcx> {
25462546
let unsafety = if abi == abi::Abi::RustIntrinsic {
2547-
intrinsic_operation_unsafety(tcx.item_name(def_id))
2547+
intrinsic_operation_unsafety(tcx, def_id)
25482548
} else {
25492549
hir::Unsafety::Unsafe
25502550
};

‎compiler/rustc_span/src/symbol.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,7 @@ symbols! {
12961296
rustc_reallocator,
12971297
rustc_regions,
12981298
rustc_reservation_impl,
1299+
rustc_safe_intrinsic,
12991300
rustc_serialize,
13001301
rustc_skip_array_during_method_dispatch,
13011302
rustc_specialization_trait,

‎library/core/src/intrinsics.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ extern "rust-intrinsic" {
788788
/// uninitialized at that point in the control flow.
789789
///
790790
/// This intrinsic should not be used outside of the compiler.
791+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
791792
pub fn rustc_peek<T>(_: T) -> T;
792793

793794
/// Aborts the execution of the process.
@@ -805,6 +806,7 @@ extern "rust-intrinsic" {
805806
/// On Unix, the
806807
/// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
807808
/// `SIGBUS`. The precise behaviour is not guaranteed and not stable.
809+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
808810
pub fn abort() -> !;
809811

810812
/// Informs the optimizer that this point in the code is not reachable,
@@ -843,6 +845,7 @@ extern "rust-intrinsic" {
843845
///
844846
/// This intrinsic does not have a stable counterpart.
845847
#[rustc_const_unstable(feature = "const_likely", issue = "none")]
848+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
846849
pub fn likely(b: bool) -> bool;
847850

848851
/// Hints to the compiler that branch condition is likely to be false.
@@ -857,6 +860,7 @@ extern "rust-intrinsic" {
857860
///
858861
/// This intrinsic does not have a stable counterpart.
859862
#[rustc_const_unstable(feature = "const_likely", issue = "none")]
863+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
860864
pub fn unlikely(b: bool) -> bool;
861865

862866
/// Executes a breakpoint trap, for inspection by a debugger.
@@ -876,6 +880,7 @@ extern "rust-intrinsic" {
876880
///
877881
/// The stabilized version of this intrinsic is [`core::mem::size_of`].
878882
#[rustc_const_stable(feature = "const_size_of", since = "1.40.0")]
883+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
879884
pub fn size_of<T>() -> usize;
880885

881886
/// The minimum alignment of a type.
@@ -887,6 +892,7 @@ extern "rust-intrinsic" {
887892
///
888893
/// The stabilized version of this intrinsic is [`core::mem::align_of`].
889894
#[rustc_const_stable(feature = "const_min_align_of", since = "1.40.0")]
895+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
890896
pub fn min_align_of<T>() -> usize;
891897
/// The preferred alignment of a type.
892898
///
@@ -915,6 +921,7 @@ extern "rust-intrinsic" {
915921
///
916922
/// The stabilized version of this intrinsic is [`core::any::type_name`].
917923
#[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
924+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
918925
pub fn type_name<T: ?Sized>() -> &'static str;
919926

920927
/// Gets an identifier which is globally unique to the specified type. This
@@ -928,27 +935,31 @@ extern "rust-intrinsic" {
928935
///
929936
/// The stabilized version of this intrinsic is [`core::any::TypeId::of`].
930937
#[rustc_const_unstable(feature = "const_type_id", issue = "77125")]
938+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
931939
pub fn type_id<T: ?Sized + 'static>() -> u64;
932940

933941
/// A guard for unsafe functions that cannot ever be executed if `T` is uninhabited:
934942
/// This will statically either panic, or do nothing.
935943
///
936944
/// This intrinsic does not have a stable counterpart.
937945
#[rustc_const_stable(feature = "const_assert_type", since = "1.59.0")]
946+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
938947
pub fn assert_inhabited<T>();
939948

940949
/// A guard for unsafe functions that cannot ever be executed if `T` does not permit
941950
/// zero-initialization: This will statically either panic, or do nothing.
942951
///
943952
/// This intrinsic does not have a stable counterpart.
944953
#[rustc_const_unstable(feature = "const_assert_type2", issue = "none")]
954+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
945955
pub fn assert_zero_valid<T>();
946956

947957
/// A guard for unsafe functions that cannot ever be executed if `T` has invalid
948958
/// bit patterns: This will statically either panic, or do nothing.
949959
///
950960
/// This intrinsic does not have a stable counterpart.
951961
#[rustc_const_unstable(feature = "const_assert_type2", issue = "none")]
962+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
952963
pub fn assert_uninit_valid<T>();
953964

954965
/// Gets a reference to a static `Location` indicating where it was called.
@@ -960,6 +971,7 @@ extern "rust-intrinsic" {
960971
///
961972
/// Consider using [`core::panic::Location::caller`] instead.
962973
#[rustc_const_unstable(feature = "const_caller_location", issue = "76156")]
974+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
963975
pub fn caller_location() -> &'static crate::panic::Location<'static>;
964976

965977
/// Moves a value out of scope without running drop glue.
@@ -972,6 +984,7 @@ extern "rust-intrinsic" {
972984
/// Therefore, implementations must not require the user to uphold
973985
/// any safety invariants.
974986
#[rustc_const_unstable(feature = "const_intrinsic_forget", issue = "none")]
987+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
975988
pub fn forget<T: ?Sized>(_: T);
976989

977990
/// Reinterprets the bits of a value of one type as another type.
@@ -1251,6 +1264,7 @@ extern "rust-intrinsic" {
12511264
///
12521265
/// The stabilized version of this intrinsic is [`mem::needs_drop`](crate::mem::needs_drop).
12531266
#[rustc_const_stable(feature = "const_needs_drop", since = "1.40.0")]
1267+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
12541268
pub fn needs_drop<T: ?Sized>() -> bool;
12551269

12561270
/// Calculates the offset from a pointer.
@@ -1295,6 +1309,7 @@ extern "rust-intrinsic" {
12951309
/// any safety invariants.
12961310
///
12971311
/// Consider using [`pointer::mask`] instead.
1312+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
12981313
pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T;
12991314

13001315
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
@@ -1486,6 +1501,7 @@ extern "rust-intrinsic" {
14861501
///
14871502
/// The stabilized version of this intrinsic is
14881503
/// [`f32::min`]
1504+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
14891505
pub fn minnumf32(x: f32, y: f32) -> f32;
14901506
/// Returns the minimum of two `f64` values.
14911507
///
@@ -1496,6 +1512,7 @@ extern "rust-intrinsic" {
14961512
///
14971513
/// The stabilized version of this intrinsic is
14981514
/// [`f64::min`]
1515+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
14991516
pub fn minnumf64(x: f64, y: f64) -> f64;
15001517
/// Returns the maximum of two `f32` values.
15011518
///
@@ -1506,6 +1523,7 @@ extern "rust-intrinsic" {
15061523
///
15071524
/// The stabilized version of this intrinsic is
15081525
/// [`f32::max`]
1526+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
15091527
pub fn maxnumf32(x: f32, y: f32) -> f32;
15101528
/// Returns the maximum of two `f64` values.
15111529
///
@@ -1516,6 +1534,7 @@ extern "rust-intrinsic" {
15161534
///
15171535
/// The stabilized version of this intrinsic is
15181536
/// [`f64::max`]
1537+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
15191538
pub fn maxnumf64(x: f64, y: f64) -> f64;
15201539

15211540
/// Copies the sign from `y` to `x` for `f32` values.
@@ -1636,6 +1655,7 @@ extern "rust-intrinsic" {
16361655
/// primitives via the `count_ones` method. For example,
16371656
/// [`u32::count_ones`]
16381657
#[rustc_const_stable(feature = "const_ctpop", since = "1.40.0")]
1658+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
16391659
pub fn ctpop<T: Copy>(x: T) -> T;
16401660

16411661
/// Returns the number of leading unset bits (zeroes) in an integer type `T`.
@@ -1673,6 +1693,7 @@ extern "rust-intrinsic" {
16731693
/// assert_eq!(num_leading, 16);
16741694
/// ```
16751695
#[rustc_const_stable(feature = "const_ctlz", since = "1.40.0")]
1696+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
16761697
pub fn ctlz<T: Copy>(x: T) -> T;
16771698

16781699
/// Like `ctlz`, but extra-unsafe as it returns `undef` when
@@ -1729,6 +1750,7 @@ extern "rust-intrinsic" {
17291750
/// assert_eq!(num_trailing, 16);
17301751
/// ```
17311752
#[rustc_const_stable(feature = "const_cttz", since = "1.40.0")]
1753+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
17321754
pub fn cttz<T: Copy>(x: T) -> T;
17331755

17341756
/// Like `cttz`, but extra-unsafe as it returns `undef` when
@@ -1761,6 +1783,7 @@ extern "rust-intrinsic" {
17611783
/// primitives via the `swap_bytes` method. For example,
17621784
/// [`u32::swap_bytes`]
17631785
#[rustc_const_stable(feature = "const_bswap", since = "1.40.0")]
1786+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
17641787
pub fn bswap<T: Copy>(x: T) -> T;
17651788

17661789
/// Reverses the bits in an integer type `T`.
@@ -1774,6 +1797,7 @@ extern "rust-intrinsic" {
17741797
/// primitives via the `reverse_bits` method. For example,
17751798
/// [`u32::reverse_bits`]
17761799
#[rustc_const_stable(feature = "const_bitreverse", since = "1.40.0")]
1800+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
17771801
pub fn bitreverse<T: Copy>(x: T) -> T;
17781802

17791803
/// Performs checked integer addition.
@@ -1787,6 +1811,7 @@ extern "rust-intrinsic" {
17871811
/// primitives via the `overflowing_add` method. For example,
17881812
/// [`u32::overflowing_add`]
17891813
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
1814+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
17901815
pub fn add_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
17911816

17921817
/// Performs checked integer subtraction
@@ -1800,6 +1825,7 @@ extern "rust-intrinsic" {
18001825
/// primitives via the `overflowing_sub` method. For example,
18011826
/// [`u32::overflowing_sub`]
18021827
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
1828+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
18031829
pub fn sub_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
18041830

18051831
/// Performs checked integer multiplication
@@ -1813,6 +1839,7 @@ extern "rust-intrinsic" {
18131839
/// primitives via the `overflowing_mul` method. For example,
18141840
/// [`u32::overflowing_mul`]
18151841
#[rustc_const_stable(feature = "const_int_overflow", since = "1.40.0")]
1842+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
18161843
pub fn mul_with_overflow<T: Copy>(x: T, y: T) -> (T, bool);
18171844

18181845
/// Performs an exact division, resulting in undefined behavior where
@@ -1887,6 +1914,7 @@ extern "rust-intrinsic" {
18871914
/// primitives via the `rotate_left` method. For example,
18881915
/// [`u32::rotate_left`]
18891916
#[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
1917+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
18901918
pub fn rotate_left<T: Copy>(x: T, y: T) -> T;
18911919

18921920
/// Performs rotate right.
@@ -1900,6 +1928,7 @@ extern "rust-intrinsic" {
19001928
/// primitives via the `rotate_right` method. For example,
19011929
/// [`u32::rotate_right`]
19021930
#[rustc_const_stable(feature = "const_int_rotate", since = "1.40.0")]
1931+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
19031932
pub fn rotate_right<T: Copy>(x: T, y: T) -> T;
19041933

19051934
/// Returns (a + b) mod 2<sup>N</sup>, where N is the width of T in bits.
@@ -1913,6 +1942,7 @@ extern "rust-intrinsic" {
19131942
/// primitives via the `wrapping_add` method. For example,
19141943
/// [`u32::wrapping_add`]
19151944
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
1945+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
19161946
pub fn wrapping_add<T: Copy>(a: T, b: T) -> T;
19171947
/// Returns (a - b) mod 2<sup>N</sup>, where N is the width of T in bits.
19181948
///
@@ -1925,6 +1955,7 @@ extern "rust-intrinsic" {
19251955
/// primitives via the `wrapping_sub` method. For example,
19261956
/// [`u32::wrapping_sub`]
19271957
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
1958+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
19281959
pub fn wrapping_sub<T: Copy>(a: T, b: T) -> T;
19291960
/// Returns (a * b) mod 2<sup>N</sup>, where N is the width of T in bits.
19301961
///
@@ -1937,6 +1968,7 @@ extern "rust-intrinsic" {
19371968
/// primitives via the `wrapping_mul` method. For example,
19381969
/// [`u32::wrapping_mul`]
19391970
#[rustc_const_stable(feature = "const_int_wrapping", since = "1.40.0")]
1971+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
19401972
pub fn wrapping_mul<T: Copy>(a: T, b: T) -> T;
19411973

19421974
/// Computes `a + b`, saturating at numeric bounds.
@@ -1950,6 +1982,7 @@ extern "rust-intrinsic" {
19501982
/// primitives via the `saturating_add` method. For example,
19511983
/// [`u32::saturating_add`]
19521984
#[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
1985+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
19531986
pub fn saturating_add<T: Copy>(a: T, b: T) -> T;
19541987
/// Computes `a - b`, saturating at numeric bounds.
19551988
///
@@ -1962,6 +1995,7 @@ extern "rust-intrinsic" {
19621995
/// primitives via the `saturating_sub` method. For example,
19631996
/// [`u32::saturating_sub`]
19641997
#[rustc_const_stable(feature = "const_int_saturating", since = "1.40.0")]
1998+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
19651999
pub fn saturating_sub<T: Copy>(a: T, b: T) -> T;
19662000

19672001
/// Returns the value of the discriminant for the variant in 'v';
@@ -1974,6 +2008,7 @@ extern "rust-intrinsic" {
19742008
///
19752009
/// The stabilized version of this intrinsic is [`core::mem::discriminant`].
19762010
#[rustc_const_unstable(feature = "const_discriminant", issue = "69821")]
2011+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
19772012
pub fn discriminant_value<T>(v: &T) -> <T as DiscriminantKind>::Discriminant;
19782013

19792014
/// Returns the number of variants of the type `T` cast to a `usize`;
@@ -1986,6 +2021,7 @@ extern "rust-intrinsic" {
19862021
///
19872022
/// The to-be-stabilized version of this intrinsic is [`mem::variant_count`].
19882023
#[rustc_const_unstable(feature = "variant_count", issue = "73662")]
2024+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
19892025
pub fn variant_count<T>() -> usize;
19902026

19912027
/// Rust's "try catch" construct which invokes the function pointer `try_fn`
@@ -2019,6 +2055,7 @@ extern "rust-intrinsic" {
20192055
/// Therefore, implementations must not require the user to uphold
20202056
/// any safety invariants.
20212057
#[rustc_const_unstable(feature = "const_raw_ptr_comparison", issue = "53020")]
2058+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
20222059
pub fn ptr_guaranteed_cmp<T>(ptr: *const T, other: *const T) -> u8;
20232060

20242061
/// Allocates a block of memory at compile time.
@@ -2069,6 +2106,7 @@ extern "rust-intrinsic" {
20692106
///
20702107
/// [`std::hint::black_box`]: crate::hint::black_box
20712108
#[rustc_const_unstable(feature = "const_black_box", issue = "none")]
2109+
#[cfg_attr(not(bootstrap), rustc_safe_intrinsic)]
20722110
pub fn black_box<T>(dummy: T) -> T;
20732111

20742112
/// `ptr` must point to a vtable.

‎src/librustdoc/clean/types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,7 @@ impl Item {
689689
let abi = tcx.fn_sig(self.item_id.as_def_id().unwrap()).abi();
690690
hir::FnHeader {
691691
unsafety: if abi == Abi::RustIntrinsic {
692-
intrinsic_operation_unsafety(self.name.unwrap())
692+
intrinsic_operation_unsafety(tcx, self.item_id.as_def_id().unwrap())
693693
} else {
694694
hir::Unsafety::Unsafe
695695
},

‎src/test/rustdoc/safe-intrinsic.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
#![feature(intrinsics)]
22
#![feature(no_core)]
3+
#![feature(rustc_attrs)]
34

45
#![no_core]
56
#![crate_name = "foo"]
67

78
extern "rust-intrinsic" {
89
// @has 'foo/fn.abort.html'
910
// @has - '//pre[@class="rust fn"]' 'pub extern "rust-intrinsic" fn abort() -> !'
11+
#[rustc_safe_intrinsic]
1012
pub fn abort() -> !;
1113
// @has 'foo/fn.unreachable.html'
1214
// @has - '//pre[@class="rust fn"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !'

‎src/test/ui/error-codes/E0094.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![feature(intrinsics)]
2+
23
extern "rust-intrinsic" {
4+
#[rustc_safe_intrinsic]
35
fn size_of<T, U>() -> usize; //~ ERROR E0094
46
}
57

‎src/test/ui/error-codes/E0094.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1
2-
--> $DIR/E0094.rs:3:15
2+
--> $DIR/E0094.rs:5:15
33
|
44
LL | fn size_of<T, U>() -> usize;
55
| ^^^^^^ expected 1 type parameter

‎src/test/ui/error-codes/E0308.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![feature(intrinsics)]
2+
#![feature(rustc_attrs)]
23

34
extern "rust-intrinsic" {
5+
#[rustc_safe_intrinsic]
46
fn size_of<T>(); //~ ERROR E0308
57
}
68

‎src/test/ui/error-codes/E0308.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0308]: intrinsic has wrong type
2-
--> $DIR/E0308.rs:4:5
2+
--> $DIR/E0308.rs:6:5
33
|
44
LL | fn size_of<T>();
55
| ^^^^^^^^^^^^^^^^ expected `()`, found `usize`

‎src/test/ui/extern/extern-with-type-bounds.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
extern "rust-intrinsic" {
44
// Real example from libcore
5+
#[rustc_safe_intrinsic]
56
fn type_id<T: ?Sized + 'static>() -> u64;
67

78
// Silent bounds made explicit to make sure they are actually
@@ -10,6 +11,7 @@ extern "rust-intrinsic" {
1011

1112
// Bounds aren't checked right now, so this should work
1213
// even though it's incorrect.
14+
#[rustc_safe_intrinsic]
1315
fn size_of<T: Clone>() -> usize;
1416

1517
// Unresolved bounds should still error.

‎src/test/ui/extern/extern-with-type-bounds.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error[E0405]: cannot find trait `NoSuchTrait` in this scope
2-
--> $DIR/extern-with-type-bounds.rs:16:20
2+
--> $DIR/extern-with-type-bounds.rs:18:20
33
|
44
LL | fn align_of<T: NoSuchTrait>() -> usize;
55
| ^^^^^^^^^^^ not found in this scope

‎src/test/ui/intrinsics/intrinsic-alignment.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
mod rusti {
77
extern "rust-intrinsic" {
88
pub fn pref_align_of<T>() -> usize;
9+
#[rustc_safe_intrinsic]
910
pub fn min_align_of<T>() -> usize;
1011
}
1112
}

‎src/test/ui/intrinsics/intrinsics-integer.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
// run-pass
22

33
#![feature(intrinsics)]
4+
#![feature(rustc_attrs)]
45

56
mod rusti {
67
extern "rust-intrinsic" {
8+
#[rustc_safe_intrinsic]
79
pub fn ctpop<T>(x: T) -> T;
10+
#[rustc_safe_intrinsic]
811
pub fn ctlz<T>(x: T) -> T;
912
pub fn ctlz_nonzero<T>(x: T) -> T;
13+
#[rustc_safe_intrinsic]
1014
pub fn cttz<T>(x: T) -> T;
1115
pub fn cttz_nonzero<T>(x: T) -> T;
16+
#[rustc_safe_intrinsic]
1217
pub fn bswap<T>(x: T) -> T;
18+
#[rustc_safe_intrinsic]
1319
pub fn bitreverse<T>(x: T) -> T;
1420
}
1521
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#![feature(intrinsics)]
2+
#![feature(rustc_attrs)]
3+
4+
extern "rust-intrinsic" {
5+
fn size_of<T>() -> usize; //~ ERROR intrinsic safety mismatch
6+
7+
#[rustc_safe_intrinsic]
8+
fn assume(b: bool); //~ ERROR intrinsic safety mismatch
9+
}
10+
11+
fn main() {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
2+
--> $DIR/safe-intrinsic-mismatch.rs:5:5
3+
|
4+
LL | fn size_of<T>() -> usize;
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
8+
--> $DIR/safe-intrinsic-mismatch.rs:8:5
9+
|
10+
LL | fn assume(b: bool);
11+
| ^^^^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+

‎src/test/ui/structs-enums/rec-align-u32.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use std::mem;
1010
mod rusti {
1111
extern "rust-intrinsic" {
1212
pub fn pref_align_of<T>() -> usize;
13+
#[rustc_safe_intrinsic]
1314
pub fn min_align_of<T>() -> usize;
1415
}
1516
}

‎src/test/ui/structs-enums/rec-align-u64.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::mem;
1212
mod rusti {
1313
extern "rust-intrinsic" {
1414
pub fn pref_align_of<T>() -> usize;
15+
#[rustc_safe_intrinsic]
1516
pub fn min_align_of<T>() -> usize;
1617
}
1718
}

0 commit comments

Comments
 (0)
Please sign in to comment.