about summary refs log tree commit diff
diff options
context:
space:
mode:
authorArthur Cohen <arthur.cohen@embecosm.com>2022-08-17 13:43:59 +0200
committerArthur Cohen <arthur.cohen@embecosm.com>2022-09-27 15:55:42 +0200
commit0ab2c91a2d8fe770d9fc47f06545367bab8ea302 (patch)
treee489a82eaf2676d5d7dd699d5fb61c9142feed23
parent57ee5cf5a93923dae9c98bffb11545fc3a31368d (diff)
downloadrust-0ab2c91a2d8fe770d9fc47f06545367bab8ea302.tar.gz
rust-0ab2c91a2d8fe770d9fc47f06545367bab8ea302.zip
attributes: Add #[rustc_safe_intrinsic] builtin
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs57
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--src/librustdoc/clean/types.rs2
-rw-r--r--src/test/rustdoc/safe-intrinsic.rs2
-rw-r--r--src/test/ui/error-codes/E0308.rs2
-rw-r--r--src/test/ui/error-codes/E0308.stderr2
-rw-r--r--src/test/ui/intrinsics/intrinsics-integer.rs6
9 files changed, 24 insertions, 51 deletions
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 700d9dab64b..5ee6c9f2387 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -499,6 +499,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
     ungated!(rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
     ungated!(rustc_const_stable, Normal, template!(List: r#"feature = "name""#), DuplicatesOk),
+    ungated!(rustc_safe_intrinsic, Normal, template!(Word), DuplicatesOk),
     ungated!(
         rustc_default_body_unstable, Normal,
         template!(List: r#"feature = "name", reason = "...", issue = "N""#), DuplicatesOk
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index ae484b4feda..b43d492eb7a 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -7,6 +7,7 @@ use crate::errors::{
 };
 use crate::require_same_types;
 
+use hir::def_id::DefId;
 use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
@@ -61,51 +62,10 @@ fn equate_intrinsic_type<'tcx>(
 }
 
 /// Returns the unsafety of the given intrinsic.
-pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
-    match intrinsic {
-        // When adding a new intrinsic to this list,
-        // it's usually worth updating that intrinsic's documentation
-        // to note that it's safe to call, since
-        // safe extern fns are otherwise unprecedented.
-        sym::abort
-        | sym::assert_inhabited
-        | sym::assert_zero_valid
-        | sym::assert_uninit_valid
-        | sym::size_of
-        | sym::min_align_of
-        | sym::needs_drop
-        | sym::caller_location
-        | sym::add_with_overflow
-        | sym::sub_with_overflow
-        | sym::mul_with_overflow
-        | sym::wrapping_add
-        | sym::wrapping_sub
-        | sym::wrapping_mul
-        | sym::saturating_add
-        | sym::saturating_sub
-        | sym::rotate_left
-        | sym::rotate_right
-        | sym::ctpop
-        | sym::ctlz
-        | sym::cttz
-        | sym::bswap
-        | sym::bitreverse
-        | sym::discriminant_value
-        | sym::type_id
-        | sym::likely
-        | sym::unlikely
-        | sym::ptr_guaranteed_cmp
-        | sym::minnumf32
-        | sym::minnumf64
-        | sym::maxnumf32
-        | sym::rustc_peek
-        | sym::maxnumf64
-        | sym::type_name
-        | sym::forget
-        | sym::black_box
-        | sym::variant_count
-        | sym::ptr_mask => hir::Unsafety::Normal,
-        _ => hir::Unsafety::Unsafe,
+pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir::Unsafety {
+    match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
+        true => hir::Unsafety::Normal,
+        false => hir::Unsafety::Unsafe,
     }
 }
 
@@ -113,7 +73,8 @@ pub fn intrinsic_operation_unsafety(intrinsic: Symbol) -> hir::Unsafety {
 /// and in `library/core/src/intrinsics.rs`.
 pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)));
-    let intrinsic_name = tcx.item_name(it.def_id.to_def_id());
+    let intrinsic_id = it.def_id.to_def_id();
+    let intrinsic_name = tcx.item_name(intrinsic_id);
     let name_str = intrinsic_name.as_str();
 
     let bound_vars = tcx.mk_bound_variable_kinds(
@@ -160,7 +121,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
         };
         (n_tps, 0, inputs, output, hir::Unsafety::Unsafe)
     } else {
-        let unsafety = intrinsic_operation_unsafety(intrinsic_name);
+        let unsafety = intrinsic_operation_unsafety(tcx, intrinsic_id);
         let (n_tps, inputs, output) = match intrinsic_name {
             sym::abort => (0, Vec::new(), tcx.types.never),
             sym::unreachable => (0, Vec::new(), tcx.types.never),
@@ -351,7 +312,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 (
                     1,
                     vec![
-                        tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0)),
+                        tcx.mk_imm_ref(tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)), param(0))
                     ],
                     tcx.mk_projection(discriminant_def_id, tcx.mk_substs([param(0).into()].iter())),
                 )
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index e7deae2b557..315a2763c76 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -2544,7 +2544,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     abi: abi::Abi,
 ) -> ty::PolyFnSig<'tcx> {
     let unsafety = if abi == abi::Abi::RustIntrinsic {
-        intrinsic_operation_unsafety(tcx.item_name(def_id))
+        intrinsic_operation_unsafety(tcx, def_id)
     } else {
         hir::Unsafety::Unsafe
     };
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 502ef67fc67..c6eff27b988 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1282,6 +1282,7 @@ symbols! {
         rustc_reallocator,
         rustc_regions,
         rustc_reservation_impl,
+        rustc_safe_intrinsic,
         rustc_serialize,
         rustc_skip_array_during_method_dispatch,
         rustc_specialization_trait,
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index e53e93c4def..80bf2f2fd90 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -689,7 +689,7 @@ impl Item {
                 let abi = tcx.fn_sig(self.item_id.as_def_id().unwrap()).abi();
                 hir::FnHeader {
                     unsafety: if abi == Abi::RustIntrinsic {
-                        intrinsic_operation_unsafety(self.name.unwrap())
+                        intrinsic_operation_unsafety(tcx, self.item_id.as_def_id().unwrap())
                     } else {
                         hir::Unsafety::Unsafe
                     },
diff --git a/src/test/rustdoc/safe-intrinsic.rs b/src/test/rustdoc/safe-intrinsic.rs
index d3bb8514b7e..d08abdaeb14 100644
--- a/src/test/rustdoc/safe-intrinsic.rs
+++ b/src/test/rustdoc/safe-intrinsic.rs
@@ -1,5 +1,6 @@
 #![feature(intrinsics)]
 #![feature(no_core)]
+#![feature(rustc_attrs)]
 
 #![no_core]
 #![crate_name = "foo"]
@@ -7,6 +8,7 @@
 extern "rust-intrinsic" {
     // @has 'foo/fn.abort.html'
     // @has - '//pre[@class="rust fn"]' 'pub extern "rust-intrinsic" fn abort() -> !'
+    #[rustc_safe_intrinsic]
     pub fn abort() -> !;
     // @has 'foo/fn.unreachable.html'
     // @has - '//pre[@class="rust fn"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !'
diff --git a/src/test/ui/error-codes/E0308.rs b/src/test/ui/error-codes/E0308.rs
index fa79bee570e..dd9e0b284ea 100644
--- a/src/test/ui/error-codes/E0308.rs
+++ b/src/test/ui/error-codes/E0308.rs
@@ -1,6 +1,8 @@
 #![feature(intrinsics)]
+#![feature(rustc_attrs)]
 
 extern "rust-intrinsic" {
+    #[rustc_safe_intrinsic]
     fn size_of<T>(); //~ ERROR E0308
 }
 
diff --git a/src/test/ui/error-codes/E0308.stderr b/src/test/ui/error-codes/E0308.stderr
index b71fb95e706..187b775f92d 100644
--- a/src/test/ui/error-codes/E0308.stderr
+++ b/src/test/ui/error-codes/E0308.stderr
@@ -1,5 +1,5 @@
 error[E0308]: intrinsic has wrong type
-  --> $DIR/E0308.rs:4:5
+  --> $DIR/E0308.rs:6:5
    |
 LL |     fn size_of<T>();
    |     ^^^^^^^^^^^^^^^^ expected `()`, found `usize`
diff --git a/src/test/ui/intrinsics/intrinsics-integer.rs b/src/test/ui/intrinsics/intrinsics-integer.rs
index bac6c8d872b..88bf42b685f 100644
--- a/src/test/ui/intrinsics/intrinsics-integer.rs
+++ b/src/test/ui/intrinsics/intrinsics-integer.rs
@@ -1,15 +1,21 @@
 // run-pass
 
 #![feature(intrinsics)]
+#![feature(rustc_attrs)]
 
 mod rusti {
     extern "rust-intrinsic" {
+        #[rustc_safe_intrinsic]
         pub fn ctpop<T>(x: T) -> T;
+        #[rustc_safe_intrinsic]
         pub fn ctlz<T>(x: T) -> T;
         pub fn ctlz_nonzero<T>(x: T) -> T;
+        #[rustc_safe_intrinsic]
         pub fn cttz<T>(x: T) -> T;
         pub fn cttz_nonzero<T>(x: T) -> T;
+        #[rustc_safe_intrinsic]
         pub fn bswap<T>(x: T) -> T;
+        #[rustc_safe_intrinsic]
         pub fn bitreverse<T>(x: T) -> T;
     }
 }