about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2023-09-25 21:40:40 +0200
committerLeón Orell Valerian Liehr <me@fmease.dev>2023-09-25 22:33:15 +0200
commitf54db7c3a927ec20dc0c20f9cd41b8e9be345bea (patch)
tree2c5470a438818e17190b61047b44e6d7f4046bc9
parentaadb5718dd9a2f4b9c64893baedfe1f5991d6bbd (diff)
downloadrust-f54db7c3a927ec20dc0c20f9cd41b8e9be345bea.tar.gz
rust-f54db7c3a927ec20dc0c20f9cd41b8e9be345bea.zip
Gate and validate #[rustc_safe_intrinsic]
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0094.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0211.md4
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs5
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs26
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--tests/ui/error-codes/E0094.rs2
-rw-r--r--tests/ui/extern/extern-with-type-bounds.rs2
-rw-r--r--tests/ui/intrinsics/feature-gate-safe-intrinsic.rs6
-rw-r--r--tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr20
-rw-r--r--tests/ui/intrinsics/intrinsic-alignment.rs2
-rw-r--r--tests/ui/repr/16-bit-repr-c-enum.rs2
-rw-r--r--tests/ui/structs-enums/rec-align-u32.rs2
-rw-r--r--tests/ui/structs-enums/rec-align-u64.rs2
14 files changed, 79 insertions, 11 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md
index 67a8c3678c5..d8c1a3cb55c 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0094.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0094.md
@@ -3,7 +3,7 @@ An invalid number of generic parameters was passed to an intrinsic function.
 Erroneous code example:
 
 ```compile_fail,E0094
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
@@ -18,7 +18,7 @@ and verify with the function declaration in the Rust source code.
 Example:
 
 ```
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
diff --git a/compiler/rustc_error_codes/src/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md
index 70f14fffae6..19a482f6c93 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0211.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0211.md
@@ -4,7 +4,7 @@ You used a function or type which doesn't fit the requirements for where it was
 used. Erroneous code examples:
 
 ```compile_fail
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
@@ -41,7 +41,7 @@ impl Foo {
 For the first code example, please check the function definition. Example:
 
 ```
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 04ebe22a9eb..18397af565f 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -537,7 +537,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         allow_internal_unsafe, Normal, template!(Word), WarnFollowing,
         "allow_internal_unsafe side-steps the unsafe_code lint",
     ),
-    ungated!(rustc_safe_intrinsic, Normal, template!(Word), DuplicatesOk),
     rustc_attr!(rustc_allowed_through_unstable_modules, Normal, template!(Word), WarnFollowing,
     "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
     through unstable paths"),
@@ -806,6 +805,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
         r#"`rustc_doc_primitive` is a rustc internal attribute"#,
     ),
+    rustc_attr!(
+        rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
+        "the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
+    ),
 
     // ==========================================================================
     // Internal attributes, Testing:
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index dc0776c5dad..214c6d70960 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -648,6 +648,10 @@ passes_rustc_lint_opt_ty =
     `#[rustc_lint_opt_ty]` should be applied to a struct
     .label = not a struct
 
+passes_rustc_safe_intrinsic =
+    attribute should be applied to intrinsic functions
+    .label = not an intrinsic function
+
 passes_rustc_std_internal_symbol =
     attribute should be applied to functions or statics
     .label = not a function or static
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 12118a0268b..0296215c8f9 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -195,6 +195,9 @@ impl CheckAttrVisitor<'_> {
                 | sym::rustc_promotable => self.check_stability_promotable(&attr, span, target),
                 sym::link_ordinal => self.check_link_ordinal(&attr, span, target),
                 sym::rustc_confusables => self.check_confusables(&attr, target),
+                sym::rustc_safe_intrinsic => {
+                    self.check_rustc_safe_intrinsic(hir_id, attr, span, target)
+                }
                 _ => true,
             };
 
@@ -2042,6 +2045,29 @@ impl CheckAttrVisitor<'_> {
         }
     }
 
+    fn check_rustc_safe_intrinsic(
+        &self,
+        hir_id: HirId,
+        attr: &Attribute,
+        span: Span,
+        target: Target,
+    ) -> bool {
+        let hir = self.tcx.hir();
+
+        if let Target::ForeignFn = target
+            && let Some(parent) = hir.opt_parent_id(hir_id)
+            && let hir::Node::Item(Item {
+                kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic | Abi::PlatformIntrinsic, .. },
+                ..
+            }) = hir.get(parent)
+        {
+            return true;
+        }
+
+        self.tcx.sess.emit_err(errors::RustcSafeIntrinsic { attr_span: attr.span, span });
+        false
+    }
+
     fn check_rustc_std_internal_symbol(
         &self,
         attr: &Attribute,
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 2ec6a0b9241..bcf5abbfe7d 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -621,6 +621,15 @@ pub struct RustcAllowConstFnUnstable {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_rustc_safe_intrinsic)]
+pub struct RustcSafeIntrinsic {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_rustc_std_internal_symbol)]
 pub struct RustcStdInternalSymbol {
     #[primary_span]
diff --git a/tests/ui/error-codes/E0094.rs b/tests/ui/error-codes/E0094.rs
index a2ec932c124..97ebcff99dc 100644
--- a/tests/ui/error-codes/E0094.rs
+++ b/tests/ui/error-codes/E0094.rs
@@ -1,4 +1,4 @@
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 extern "rust-intrinsic" {
     #[rustc_safe_intrinsic]
diff --git a/tests/ui/extern/extern-with-type-bounds.rs b/tests/ui/extern/extern-with-type-bounds.rs
index a72aa4171a1..99e9801fd40 100644
--- a/tests/ui/extern/extern-with-type-bounds.rs
+++ b/tests/ui/extern/extern-with-type-bounds.rs
@@ -1,4 +1,4 @@
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 extern "rust-intrinsic" {
     // Real example from libcore
diff --git a/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs b/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs
new file mode 100644
index 00000000000..ffaa4d771d9
--- /dev/null
+++ b/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs
@@ -0,0 +1,6 @@
+#[rustc_safe_intrinsic]
+//~^ ERROR the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe
+//~| ERROR attribute should be applied to intrinsic functions
+fn safe() {}
+
+fn main() {}
diff --git a/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr b/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr
new file mode 100644
index 00000000000..8aeb56598ec
--- /dev/null
+++ b/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr
@@ -0,0 +1,20 @@
+error[E0658]: the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe
+  --> $DIR/feature-gate-safe-intrinsic.rs:1:1
+   |
+LL | #[rustc_safe_intrinsic]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
+
+error: attribute should be applied to intrinsic functions
+  --> $DIR/feature-gate-safe-intrinsic.rs:1:1
+   |
+LL | #[rustc_safe_intrinsic]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | fn safe() {}
+   | ------------ not an intrinsic function
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs
index 30b8a21269a..6f9df64417e 100644
--- a/tests/ui/intrinsics/intrinsic-alignment.rs
+++ b/tests/ui/intrinsics/intrinsic-alignment.rs
@@ -1,7 +1,7 @@
 // run-pass
 // ignore-wasm32-bare seems not important to test here
 
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 mod rusti {
     extern "rust-intrinsic" {
diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs
index 2acfde4be46..d4fea2b192b 100644
--- a/tests/ui/repr/16-bit-repr-c-enum.rs
+++ b/tests/ui/repr/16-bit-repr-c-enum.rs
@@ -5,7 +5,7 @@
 // [avr] compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib
 // [msp430] needs-llvm-components: msp430
 // [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib
-#![feature(no_core, lang_items, intrinsics, staged_api)]
+#![feature(no_core, lang_items, intrinsics, staged_api, rustc_attrs)]
 #![no_core]
 #![crate_type = "lib"]
 #![stable(feature = "", since = "")]
diff --git a/tests/ui/structs-enums/rec-align-u32.rs b/tests/ui/structs-enums/rec-align-u32.rs
index ee704198d19..b3c323d2a29 100644
--- a/tests/ui/structs-enums/rec-align-u32.rs
+++ b/tests/ui/structs-enums/rec-align-u32.rs
@@ -3,7 +3,7 @@
 #![allow(unused_unsafe)]
 // Issue #2303
 
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 use std::mem;
 
diff --git a/tests/ui/structs-enums/rec-align-u64.rs b/tests/ui/structs-enums/rec-align-u64.rs
index c3b201fb1c6..de008bcc01d 100644
--- a/tests/ui/structs-enums/rec-align-u64.rs
+++ b/tests/ui/structs-enums/rec-align-u64.rs
@@ -5,7 +5,7 @@
 
 // Issue #2303
 
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 use std::mem;