about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-11-07 08:59:43 +0100
committerRalf Jung <post@ralfj.de>2024-11-08 09:16:00 +0100
commite3010e84dbf2e06424c91c5a3d4206c1911813bd (patch)
treee79c95932b5c88f5313d5eb5e45b3c3c41ed7b9f
parent78bb5ee79e0261e8e47476b631da02acc1cb03ef (diff)
downloadrust-e3010e84dbf2e06424c91c5a3d4206c1911813bd.tar.gz
rust-e3010e84dbf2e06424c91c5a3d4206c1911813bd.zip
remove support for rustc_safe_intrinsic attribute; use rustc_intrinsic functions instead
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core.rs83
-rw-r--r--compiler/rustc_codegen_gcc/example/mini_core.rs86
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/abort1.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/abort2.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/array.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/assign.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/closure.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/condition.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/mut_ref.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/operations.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/slice.rs8
-rw-r--r--compiler/rustc_codegen_gcc/tests/run/static.rs8
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0094.md22
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0211.md10
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs8
-rw-r--r--compiler/rustc_middle/src/ty/util.rs6
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs22
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--library/core/src/intrinsics/mod.rs180
-rw-r--r--src/doc/unstable-book/src/language-features/intrinsics.md4
-rw-r--r--src/tools/miri/tests/fail/intrinsic_fallback_is_spec.rs2
-rw-r--r--tests/assembly/rust-abi-arg-attr.rs7
-rw-r--r--tests/rustdoc/safe-intrinsic.rs25
-rw-r--r--tests/ui/error-codes/E0094.rs13
-rw-r--r--tests/ui/error-codes/E0094.stderr6
-rw-r--r--tests/ui/error-codes/E0308.rs11
-rw-r--r--tests/ui/error-codes/E0308.stderr10
-rw-r--r--tests/ui/extern/extern-with-type-bounds.rs11
-rw-r--r--tests/ui/extern/extern-with-type-bounds.stderr2
-rw-r--r--tests/ui/intrinsics/always-gets-overridden.rs2
-rw-r--r--tests/ui/intrinsics/feature-gate-safe-intrinsic.rs6
-rw-r--r--tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr21
-rw-r--r--tests/ui/intrinsics/intrinsic-alignment.rs10
-rw-r--r--tests/ui/intrinsics/intrinsics-integer.rs22
-rw-r--r--tests/ui/intrinsics/not-overridden.rs2
-rw-r--r--tests/ui/structs-enums/rec-align-u32.rs15
-rw-r--r--tests/ui/structs-enums/rec-align-u64.rs15
42 files changed, 380 insertions, 348 deletions
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs
index 42c7f5f0dc6..3da215fe6c0 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs
@@ -616,25 +616,70 @@ pub union MaybeUninit<T> {
 }
 
 pub mod intrinsics {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
-        #[rustc_safe_intrinsic]
-        pub fn size_of<T>() -> usize;
-        pub fn size_of_val<T: ?::Sized>(val: *const T) -> usize;
-        #[rustc_safe_intrinsic]
-        pub fn min_align_of<T>() -> usize;
-        pub fn min_align_of_val<T: ?::Sized>(val: *const T) -> usize;
-        pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
-        pub fn transmute<T, U>(e: T) -> U;
-        pub fn ctlz_nonzero<T>(x: T) -> u32;
-        #[rustc_safe_intrinsic]
-        pub fn needs_drop<T: ?::Sized>() -> bool;
-        #[rustc_safe_intrinsic]
-        pub fn bitreverse<T>(x: T) -> T;
-        #[rustc_safe_intrinsic]
-        pub fn bswap<T>(x: T) -> T;
-        pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn size_of<T>() -> usize {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn min_align_of<T>() -> usize {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize) {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn transmute<T, U>(_e: T) -> U {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32 {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn needs_drop<T: ?::Sized>() -> bool {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn bitreverse<T>(_x: T) -> T {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn bswap<T>(_x: T) -> T {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize) {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn unreachable() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/example/mini_core.rs b/compiler/rustc_codegen_gcc/example/mini_core.rs
index 0576b64ef6f..c887598f6e9 100644
--- a/compiler/rustc_codegen_gcc/example/mini_core.rs
+++ b/compiler/rustc_codegen_gcc/example/mini_core.rs
@@ -579,28 +579,70 @@ pub union MaybeUninit<T> {
 }
 
 pub mod intrinsics {
-    use crate::Sized;
-
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
-        #[rustc_safe_intrinsic]
-        pub fn size_of<T>() -> usize;
-        pub fn size_of_val<T: ?Sized>(val: *const T) -> usize;
-        #[rustc_safe_intrinsic]
-        pub fn min_align_of<T>() -> usize;
-        pub fn min_align_of_val<T: ?Sized>(val: *const T) -> usize;
-        pub fn copy<T>(src: *const T, dst: *mut T, count: usize);
-        pub fn transmute<T, U>(e: T) -> U;
-        pub fn ctlz_nonzero<T>(x: T) -> u32;
-        #[rustc_safe_intrinsic]
-        pub fn needs_drop<T: ?Sized>() -> bool;
-        #[rustc_safe_intrinsic]
-        pub fn bitreverse<T>(x: T) -> T;
-        #[rustc_safe_intrinsic]
-        pub fn bswap<T>(x: T) -> T;
-        pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
-        pub fn unreachable() -> !;
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn size_of<T>() -> usize {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn size_of_val<T: ?::Sized>(_val: *const T) -> usize {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn min_align_of<T>() -> usize {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn min_align_of_val<T: ?::Sized>(_val: *const T) -> usize {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn copy<T>(_src: *const T, _dst: *mut T, _count: usize) {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn transmute<T, U>(_e: T) -> U {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn ctlz_nonzero<T>(_x: T) -> u32 {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn needs_drop<T: ?::Sized>() -> bool {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn bitreverse<T>(_x: T) -> T {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn bswap<T>(_x: T) -> T {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn write_bytes<T>(_dst: *mut T, _val: u8, _count: usize) {
+        loop {}
+    }
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub unsafe fn unreachable() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/abort1.rs b/compiler/rustc_codegen_gcc/tests/run/abort1.rs
index 44297e12779..696197d7377 100644
--- a/compiler/rustc_codegen_gcc/tests/run/abort1.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/abort1.rs
@@ -33,9 +33,11 @@ pub(crate) unsafe auto trait Freeze {}
 mod intrinsics {
     use super::Sized;
 
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/abort2.rs b/compiler/rustc_codegen_gcc/tests/run/abort2.rs
index ce816927123..714cd6c0f38 100644
--- a/compiler/rustc_codegen_gcc/tests/run/abort2.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/abort2.rs
@@ -33,9 +33,11 @@ pub(crate) unsafe auto trait Freeze {}
 mod intrinsics {
     use super::Sized;
 
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/array.rs b/compiler/rustc_codegen_gcc/tests/run/array.rs
index 432f11ad8d4..d8de9f28d4c 100644
--- a/compiler/rustc_codegen_gcc/tests/run/array.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/array.rs
@@ -106,9 +106,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 }
 
 mod intrinsics {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/assign.rs b/compiler/rustc_codegen_gcc/tests/run/assign.rs
index e105d64a8ad..2a47f0c2966 100644
--- a/compiler/rustc_codegen_gcc/tests/run/assign.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/assign.rs
@@ -56,9 +56,11 @@ mod libc {
 }
 
 mod intrinsics {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/closure.rs b/compiler/rustc_codegen_gcc/tests/run/closure.rs
index 00e61cc001f..b0d0ca4ee8d 100644
--- a/compiler/rustc_codegen_gcc/tests/run/closure.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/closure.rs
@@ -98,9 +98,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 }
 
 mod intrinsics {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/condition.rs b/compiler/rustc_codegen_gcc/tests/run/condition.rs
index 7b05b7decd3..770b18a89e3 100644
--- a/compiler/rustc_codegen_gcc/tests/run/condition.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/condition.rs
@@ -109,9 +109,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 }
 
 mod intrinsics {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
index 4e96f376555..523544ee6bb 100644
--- a/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/fun_ptr.rs
@@ -103,9 +103,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 }
 
 mod intrinsics {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
index 5a3f72b6904..3ae79338216 100644
--- a/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/mut_ref.rs
@@ -58,9 +58,11 @@ mod libc {
 }
 
 mod intrinsics {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/operations.rs b/compiler/rustc_codegen_gcc/tests/run/operations.rs
index d697bd921cd..2e3c021d5f7 100644
--- a/compiler/rustc_codegen_gcc/tests/run/operations.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/operations.rs
@@ -64,9 +64,11 @@ mod libc {
 }
 
 mod intrinsics {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
index a94279182d6..c7510d16449 100644
--- a/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/ptr_cast.rs
@@ -103,9 +103,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 }
 
 mod intrinsics {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/slice.rs b/compiler/rustc_codegen_gcc/tests/run/slice.rs
index e86fc823a1a..35ad594ecde 100644
--- a/compiler/rustc_codegen_gcc/tests/run/slice.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/slice.rs
@@ -103,9 +103,11 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
 mod intrinsics {
     use super::Sized;
 
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_codegen_gcc/tests/run/static.rs b/compiler/rustc_codegen_gcc/tests/run/static.rs
index 6247e08f5e3..a17ea2a4893 100644
--- a/compiler/rustc_codegen_gcc/tests/run/static.rs
+++ b/compiler/rustc_codegen_gcc/tests/run/static.rs
@@ -46,9 +46,11 @@ pub(crate) unsafe auto trait Freeze {}
 mod intrinsics {
     use super::Sized;
 
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn abort() -> !;
+    #[rustc_nounwind]
+    #[rustc_intrinsic]
+    #[rustc_intrinsic_must_be_overridden]
+    pub fn abort() -> ! {
+        loop {}
     }
 }
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md
index d8c1a3cb55c..efbfa0851a8 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0094.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0094.md
@@ -3,13 +3,15 @@ An invalid number of generic parameters was passed to an intrinsic function.
 Erroneous code example:
 
 ```compile_fail,E0094
-#![feature(intrinsics, rustc_attrs)]
+#![feature(intrinsics)]
 #![allow(internal_features)]
 
-extern "rust-intrinsic" {
-    #[rustc_safe_intrinsic]
-    fn size_of<T, U>() -> usize; // error: intrinsic has wrong number
-                                 //        of type parameters
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+fn size_of<T, U>() -> usize // error: intrinsic has wrong number
+                            //        of type parameters
+{
+    loop {}
 }
 ```
 
@@ -18,11 +20,13 @@ and verify with the function declaration in the Rust source code.
 Example:
 
 ```
-#![feature(intrinsics, rustc_attrs)]
+#![feature(intrinsics)]
 #![allow(internal_features)]
 
-extern "rust-intrinsic" {
-    #[rustc_safe_intrinsic]
-    fn size_of<T>() -> usize; // ok!
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+fn size_of<T>() -> usize // ok!
+{
+    loop {}
 }
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md
index 19a482f6c93..7aa42628549 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0211.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0211.md
@@ -4,12 +4,11 @@ You used a function or type which doesn't fit the requirements for where it was
 used. Erroneous code examples:
 
 ```compile_fail
-#![feature(intrinsics, rustc_attrs)]
+#![feature(intrinsics)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
-    #[rustc_safe_intrinsic]
-    fn size_of<T>(); // error: intrinsic has wrong type
+    fn unreachable(); // error: intrinsic has wrong type
 }
 
 // or:
@@ -41,12 +40,11 @@ impl Foo {
 For the first code example, please check the function definition. Example:
 
 ```
-#![feature(intrinsics, rustc_attrs)]
+#![feature(intrinsics)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
-    #[rustc_safe_intrinsic]
-    fn size_of<T>() -> usize; // ok!
+    fn unreachable() -> !; // ok!
 }
 ```
 
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index cc0bdec7019..a4820ba8b72 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -997,23 +997,18 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
         EncodeCrossCrate::Yes, r#"`rustc_doc_primitive` is a rustc internal attribute"#,
     ),
-    rustc_attr!(
-        rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
-        EncodeCrossCrate::No,
-        "the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
-    ),
-    rustc_attr!(
-        rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes,
+    gated!(
+        rustc_intrinsic, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
         "the `#[rustc_intrinsic]` attribute is used to declare intrinsics with function bodies",
     ),
+    gated!(
+        rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes, intrinsics,
+        "the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies",
+    ),
     rustc_attr!(
         rustc_no_mir_inline, Normal, template!(Word), WarnFollowing, EncodeCrossCrate::Yes,
         "#[rustc_no_mir_inline] prevents the MIR inliner from inlining a function while not affecting codegen"
     ),
-    rustc_attr!(
-        rustc_intrinsic_must_be_overridden, Normal, template!(Word), ErrorFollowing, EncodeCrossCrate::Yes,
-        "the `#[rustc_intrinsic_must_be_overridden]` attribute is used to declare intrinsics without real bodies",
-    ),
 
     // ==========================================================================
     // Internal attributes, Testing:
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index c465d8050a7..cb954b0adcb 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -3,7 +3,7 @@
 use rustc_abi::ExternAbi;
 use rustc_errors::codes::*;
 use rustc_errors::{DiagMessage, struct_span_code_err};
-use rustc_hir as hir;
+use rustc_hir::{self as hir, Safety};
 use rustc_middle::bug;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -75,10 +75,8 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
     let has_safe_attr = if tcx.has_attr(intrinsic_id, sym::rustc_intrinsic) {
         tcx.fn_sig(intrinsic_id).skip_binder().safety()
     } else {
-        match tcx.has_attr(intrinsic_id, sym::rustc_safe_intrinsic) {
-            true => hir::Safety::Safe,
-            false => hir::Safety::Unsafe,
-        }
+        // Old-style intrinsics are never safe
+        Safety::Unsafe
     };
     let is_in_list = match tcx.item_name(intrinsic_id.into()) {
         // When adding a new intrinsic to this list,
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 56e723ab517..fc5a3b762e5 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -1785,9 +1785,9 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 /// the compiler to make some assumptions about its shape; if the user doesn't use a feature gate, they may
 /// cause an ICE that we otherwise may want to prevent.
 pub fn intrinsic_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::IntrinsicDef> {
-    if (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
-        && tcx.features().intrinsics())
-        || (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs())
+    if tcx.features().intrinsics()
+        && (matches!(tcx.fn_sig(def_id).skip_binder().abi(), ExternAbi::RustIntrinsic)
+            || tcx.has_attr(def_id, sym::rustc_intrinsic))
     {
         Some(ty::IntrinsicDef {
             name: tcx.item_name(def_id.into()),
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index e5e70ba2033..6f0bcf5c3f0 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -679,10 +679,6 @@ passes_rustc_pub_transparent =
     attribute should be applied to `#[repr(transparent)]` types
     .label = not a `#[repr(transparent)]` type
 
-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 0a2926c0404..64a527ef106 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -210,9 +210,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 | [sym::rustc_promotable, ..] => self.check_stability_promotable(attr, 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)
-                }
                 [sym::cold, ..] => self.check_cold(hir_id, attr, span, target),
                 [sym::link, ..] => self.check_link(hir_id, attr, span, target),
                 [sym::link_name, ..] => self.check_link_name(hir_id, attr, span, target),
@@ -2055,25 +2052,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_rustc_safe_intrinsic(
-        &self,
-        hir_id: HirId,
-        attr: &Attribute,
-        span: Span,
-        target: Target,
-    ) {
-        if let Target::ForeignFn = target
-            && let hir::Node::Item(Item {
-                kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic, .. },
-                ..
-            }) = self.tcx.parent_hir_node(hir_id)
-        {
-            return;
-        }
-
-        self.dcx().emit_err(errors::RustcSafeIntrinsic { attr_span: attr.span, span });
-    }
-
     fn check_rustc_std_internal_symbol(&self, attr: &Attribute, span: Span, target: Target) {
         match target {
             Target::Fn | Target::Static => {}
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 8bd767c1243..70c92f0144c 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -642,15 +642,6 @@ pub(crate) struct RustcAllowConstFnUnstable {
 }
 
 #[derive(Diagnostic)]
-#[diag(passes_rustc_safe_intrinsic)]
-pub(crate) struct RustcSafeIntrinsic {
-    #[primary_span]
-    pub attr_span: Span,
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(passes_rustc_std_internal_symbol)]
 pub(crate) struct RustcStdInternalSymbol {
     #[primary_span]
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index cb107b0607e..82cfbd28fff 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1733,7 +1733,6 @@ symbols! {
         rustc_reallocator,
         rustc_regions,
         rustc_reservation_impl,
-        rustc_safe_intrinsic,
         rustc_serialize,
         rustc_skip_during_method_dispatch,
         rustc_specialization_trait,
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index d33a403cfda..b6e22c42eee 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -904,38 +904,6 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn prefetch_write_instruction<T>(data: *const T, locality: i32);
 
-    /// Magic intrinsic that derives its meaning from attributes
-    /// attached to the function.
-    ///
-    /// For example, dataflow uses this to inject static assertions so
-    /// that `rustc_peek(potentially_uninitialized)` would actually
-    /// double-check that dataflow did indeed compute that it is
-    /// uninitialized at that point in the control flow.
-    ///
-    /// This intrinsic should not be used outside of the compiler.
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn rustc_peek<T>(_: T) -> T;
-
-    /// Aborts the execution of the process.
-    ///
-    /// Note that, unlike most intrinsics, this is safe to call;
-    /// it does not require an `unsafe` block.
-    /// Therefore, implementations must not require the user to uphold
-    /// any safety invariants.
-    ///
-    /// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible,
-    /// as its behavior is more user-friendly and more stable.
-    ///
-    /// The current implementation of `intrinsics::abort` is to invoke an invalid instruction,
-    /// on most platforms.
-    /// On Unix, the
-    /// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
-    /// `SIGBUS`.  The precise behavior is not guaranteed and not stable.
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn abort() -> !;
-
     /// Executes a breakpoint trap, for inspection by a debugger.
     ///
     /// This intrinsic does not have a stable counterpart.
@@ -943,6 +911,44 @@ extern "rust-intrinsic" {
     pub fn breakpoint();
 }
 
+/// Magic intrinsic that derives its meaning from attributes
+/// attached to the function.
+///
+/// For example, dataflow uses this to inject static assertions so
+/// that `rustc_peek(potentially_uninitialized)` would actually
+/// double-check that dataflow did indeed compute that it is
+/// uninitialized at that point in the control flow.
+///
+/// This intrinsic should not be used outside of the compiler.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub fn rustc_peek<T>(_: T) -> T {
+    unreachable!()
+}
+
+/// Aborts the execution of the process.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+///
+/// [`std::process::abort`](../../std/process/fn.abort.html) is to be preferred if possible,
+/// as its behavior is more user-friendly and more stable.
+///
+/// The current implementation of `intrinsics::abort` is to invoke an invalid instruction,
+/// on most platforms.
+/// On Unix, the
+/// process will probably terminate with a signal like `SIGABRT`, `SIGILL`, `SIGTRAP`, `SIGSEGV` or
+/// `SIGBUS`.  The precise behavior is not guaranteed and not stable.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub fn abort() -> ! {
+    unreachable!()
+}
+
 /// Informs the optimizer that this point in the code is not reachable,
 /// enabling further optimizations.
 ///
@@ -1512,19 +1518,22 @@ pub const unsafe fn arith_offset<T>(_dst: *const T, _offset: isize) -> *const T
     unreachable!()
 }
 
-extern "rust-intrinsic" {
-    /// Masks out bits of the pointer according to a mask.
-    ///
-    /// Note that, unlike most intrinsics, this is safe to call;
-    /// it does not require an `unsafe` block.
-    /// Therefore, implementations must not require the user to uphold
-    /// any safety invariants.
-    ///
-    /// Consider using [`pointer::mask`] instead.
-    #[rustc_safe_intrinsic]
-    #[rustc_nounwind]
-    pub fn ptr_mask<T>(ptr: *const T, mask: usize) -> *const T;
+/// Masks out bits of the pointer according to a mask.
+///
+/// Note that, unlike most intrinsics, this is safe to call;
+/// it does not require an `unsafe` block.
+/// Therefore, implementations must not require the user to uphold
+/// any safety invariants.
+///
+/// Consider using [`pointer::mask`] instead.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub fn ptr_mask<T>(_ptr: *const T, _mask: usize) -> *const T {
+    unreachable!()
+}
 
+extern "rust-intrinsic" {
     /// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with
     /// a size of `count` * `size_of::<T>()` and an alignment of
     /// `min_align_of::<T>()`
@@ -2140,47 +2149,62 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn frem_fast<T: Copy>(a: T, b: T) -> T;
 
-    /// Float addition that allows optimizations based on algebraic rules.
+    /// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range
+    /// (<https://github.com/rust-lang/rust/issues/10184>)
     ///
-    /// This intrinsic does not have a stable counterpart.
+    /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`].
     #[rustc_nounwind]
-    #[rustc_safe_intrinsic]
-    pub fn fadd_algebraic<T: Copy>(a: T, b: T) -> T;
+    pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+}
 
-    /// Float subtraction that allows optimizations based on algebraic rules.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    #[rustc_safe_intrinsic]
-    pub fn fsub_algebraic<T: Copy>(a: T, b: T) -> T;
+/// Float addition that allows optimizations based on algebraic rules.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub fn fadd_algebraic<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
+}
 
-    /// Float multiplication that allows optimizations based on algebraic rules.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    #[rustc_safe_intrinsic]
-    pub fn fmul_algebraic<T: Copy>(a: T, b: T) -> T;
+/// Float subtraction that allows optimizations based on algebraic rules.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub fn fsub_algebraic<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
+}
 
-    /// Float division that allows optimizations based on algebraic rules.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    #[rustc_safe_intrinsic]
-    pub fn fdiv_algebraic<T: Copy>(a: T, b: T) -> T;
+/// Float multiplication that allows optimizations based on algebraic rules.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub fn fmul_algebraic<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
+}
 
-    /// Float remainder that allows optimizations based on algebraic rules.
-    ///
-    /// This intrinsic does not have a stable counterpart.
-    #[rustc_nounwind]
-    #[rustc_safe_intrinsic]
-    pub fn frem_algebraic<T: Copy>(a: T, b: T) -> T;
+/// Float division that allows optimizations based on algebraic rules.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub fn fdiv_algebraic<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
+}
 
-    /// Converts with LLVM’s fptoui/fptosi, which may return undef for values out of range
-    /// (<https://github.com/rust-lang/rust/issues/10184>)
-    ///
-    /// Stabilized as [`f32::to_int_unchecked`] and [`f64::to_int_unchecked`].
-    #[rustc_nounwind]
-    pub fn float_to_int_unchecked<Float: Copy, Int: Copy>(value: Float) -> Int;
+/// Float remainder that allows optimizations based on algebraic rules.
+///
+/// This intrinsic does not have a stable counterpart.
+#[rustc_nounwind]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub fn frem_algebraic<T: Copy>(_a: T, _b: T) -> T {
+    unimplemented!()
 }
 
 /// Returns the number of bits set in an integer type `T`
diff --git a/src/doc/unstable-book/src/language-features/intrinsics.md b/src/doc/unstable-book/src/language-features/intrinsics.md
index c262d3f6da1..13a6814d31b 100644
--- a/src/doc/unstable-book/src/language-features/intrinsics.md
+++ b/src/doc/unstable-book/src/language-features/intrinsics.md
@@ -18,7 +18,7 @@ All intrinsic fallback bodies are automatically made cross-crate inlineable (lik
 by the codegen backend, but not the MIR inliner.
 
 ```rust
-#![feature(rustc_attrs)]
+#![feature(intrinsics)]
 #![allow(internal_features)]
 
 #[rustc_intrinsic]
@@ -28,7 +28,7 @@ const unsafe fn const_deallocate(_ptr: *mut u8, _size: usize, _align: usize) {}
 Since these are just regular functions, it is perfectly ok to create the intrinsic twice:
 
 ```rust
-#![feature(rustc_attrs)]
+#![feature(intrinsics)]
 #![allow(internal_features)]
 
 #[rustc_intrinsic]
diff --git a/src/tools/miri/tests/fail/intrinsic_fallback_is_spec.rs b/src/tools/miri/tests/fail/intrinsic_fallback_is_spec.rs
index fa7c0bf5c0c..e95ef4d9062 100644
--- a/src/tools/miri/tests/fail/intrinsic_fallback_is_spec.rs
+++ b/src/tools/miri/tests/fail/intrinsic_fallback_is_spec.rs
@@ -1,4 +1,4 @@
-#![feature(rustc_attrs)]
+#![feature(intrinsics, rustc_attrs)]
 
 #[rustc_intrinsic]
 #[rustc_nounwind]
diff --git a/tests/assembly/rust-abi-arg-attr.rs b/tests/assembly/rust-abi-arg-attr.rs
index 2a113eed4ba..e55a53fbdeb 100644
--- a/tests/assembly/rust-abi-arg-attr.rs
+++ b/tests/assembly/rust-abi-arg-attr.rs
@@ -50,9 +50,10 @@ enum Ordering {
     Greater = 1,
 }
 
-extern "rust-intrinsic" {
-    #[rustc_safe_intrinsic]
-    fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> Ordering;
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+fn three_way_compare<T: Copy>(lhs: T, rhs: T) -> Ordering {
+    loop {}
 }
 
 // ^^^^^ core
diff --git a/tests/rustdoc/safe-intrinsic.rs b/tests/rustdoc/safe-intrinsic.rs
index b46ffed99c3..07af04ace60 100644
--- a/tests/rustdoc/safe-intrinsic.rs
+++ b/tests/rustdoc/safe-intrinsic.rs
@@ -5,18 +5,17 @@
 #![no_core]
 #![crate_name = "foo"]
 
-extern "rust-intrinsic" {
-    //@ has 'foo/fn.abort.html'
-    //@ has - '//pre[@class="rust item-decl"]' 'pub extern "rust-intrinsic" fn abort() -> !'
-    #[rustc_safe_intrinsic]
-    pub fn abort() -> !;
-    //@ has 'foo/fn.unreachable.html'
-    //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "rust-intrinsic" fn unreachable() -> !'
-    pub fn unreachable() -> !;
+//@ has 'foo/fn.abort.html'
+//@ has - '//pre[@class="rust item-decl"]' 'pub fn abort() -> !'
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub fn abort() -> ! {
+    loop {}
 }
-
-extern "C" {
-    //@ has 'foo/fn.needs_drop.html'
-    //@ has - '//pre[@class="rust item-decl"]' 'pub unsafe extern "C" fn needs_drop() -> !'
-    pub fn needs_drop() -> !;
+//@ has 'foo/fn.unreachable.html'
+//@ has - '//pre[@class="rust item-decl"]' 'pub unsafe fn unreachable() -> !'
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+pub unsafe fn unreachable() -> ! {
+    loop {}
 }
diff --git a/tests/ui/error-codes/E0094.rs b/tests/ui/error-codes/E0094.rs
index 97ebcff99dc..da59d3decac 100644
--- a/tests/ui/error-codes/E0094.rs
+++ b/tests/ui/error-codes/E0094.rs
@@ -1,9 +1,10 @@
-#![feature(intrinsics, rustc_attrs)]
+#![feature(intrinsics)]
 
-extern "rust-intrinsic" {
-    #[rustc_safe_intrinsic]
-    fn size_of<T, U>() -> usize; //~ ERROR E0094
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+fn size_of<T, U>() -> usize {
+    //~^ ERROR E0094
+    loop {}
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/error-codes/E0094.stderr b/tests/ui/error-codes/E0094.stderr
index 1bad5bd950e..e45cc0ea063 100644
--- a/tests/ui/error-codes/E0094.stderr
+++ b/tests/ui/error-codes/E0094.stderr
@@ -1,8 +1,8 @@
 error[E0094]: intrinsic has wrong number of type parameters: found 2, expected 1
-  --> $DIR/E0094.rs:5:15
+  --> $DIR/E0094.rs:5:11
    |
-LL |     fn size_of<T, U>() -> usize;
-   |               ^^^^^^ expected 1 type parameter
+LL | fn size_of<T, U>() -> usize {
+   |           ^^^^^^ expected 1 type parameter
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-codes/E0308.rs b/tests/ui/error-codes/E0308.rs
index dd9e0b284ea..f8f93d49a8e 100644
--- a/tests/ui/error-codes/E0308.rs
+++ b/tests/ui/error-codes/E0308.rs
@@ -1,10 +1,11 @@
 #![feature(intrinsics)]
 #![feature(rustc_attrs)]
 
-extern "rust-intrinsic" {
-    #[rustc_safe_intrinsic]
-    fn size_of<T>(); //~ ERROR E0308
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+fn size_of<T>() {
+    //~^ ERROR E0308
+    loop {}
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/error-codes/E0308.stderr b/tests/ui/error-codes/E0308.stderr
index 709b3119276..77e5c06e06a 100644
--- a/tests/ui/error-codes/E0308.stderr
+++ b/tests/ui/error-codes/E0308.stderr
@@ -1,11 +1,11 @@
 error[E0308]: intrinsic has wrong type
-  --> $DIR/E0308.rs:6:20
+  --> $DIR/E0308.rs:6:16
    |
-LL |     fn size_of<T>();
-   |                    ^ expected `usize`, found `()`
+LL | fn size_of<T>() {
+   |                ^ expected `usize`, found `()`
    |
-   = note: expected signature `extern "rust-intrinsic" fn() -> usize`
-              found signature `extern "rust-intrinsic" fn() -> ()`
+   = note: expected signature `fn() -> usize`
+              found signature `fn() -> ()`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/extern/extern-with-type-bounds.rs b/tests/ui/extern/extern-with-type-bounds.rs
index 99e9801fd40..3fbddfc99a6 100644
--- a/tests/ui/extern/extern-with-type-bounds.rs
+++ b/tests/ui/extern/extern-with-type-bounds.rs
@@ -1,18 +1,17 @@
 #![feature(intrinsics, rustc_attrs)]
 
-extern "rust-intrinsic" {
-    // Real example from libcore
-    #[rustc_safe_intrinsic]
-    fn type_id<T: ?Sized + 'static>() -> u64;
+// Intrinsics are the only (?) extern blocks supporting generics.
+// Once intrinsics have to be declared via `#[rustc_intrinsic]`,
+// the entire support for generics in extern fn can probably be removed.
 
+extern "rust-intrinsic" {
     // Silent bounds made explicit to make sure they are actually
     // resolved.
     fn transmute<T: Sized, U: Sized>(val: T) -> U;
 
     // Bounds aren't checked right now, so this should work
     // even though it's incorrect.
-    #[rustc_safe_intrinsic]
-    fn size_of<T: Clone>() -> usize;
+    fn size_of_val<T: Clone>(x: *const T) -> usize;
 
     // Unresolved bounds should still error.
     fn align_of<T: NoSuchTrait>() -> usize;
diff --git a/tests/ui/extern/extern-with-type-bounds.stderr b/tests/ui/extern/extern-with-type-bounds.stderr
index 42448d9e924..893947e831f 100644
--- a/tests/ui/extern/extern-with-type-bounds.stderr
+++ b/tests/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:18:20
+  --> $DIR/extern-with-type-bounds.rs:17:20
    |
 LL |     fn align_of<T: NoSuchTrait>() -> usize;
    |                    ^^^^^^^^^^^ not found in this scope
diff --git a/tests/ui/intrinsics/always-gets-overridden.rs b/tests/ui/intrinsics/always-gets-overridden.rs
index ad2c2be4daa..2fb64f96d83 100644
--- a/tests/ui/intrinsics/always-gets-overridden.rs
+++ b/tests/ui/intrinsics/always-gets-overridden.rs
@@ -1,6 +1,6 @@
 //! Check that `vtable_size` gets overridden by llvm backend even if there is no
 //! `rustc_intrinsic_must_be_overridden` attribute on this usage.
-#![feature(rustc_attrs)]
+#![feature(intrinsics)]
 //@run-pass
 
 #[rustc_intrinsic]
diff --git a/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs b/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs
deleted file mode 100644
index ffaa4d771d9..00000000000
--- a/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#[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
deleted file mode 100644
index e49880e9bb8..00000000000
--- a/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-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
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-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 4cb05f6a8df..ab99aa5fd03 100644
--- a/tests/ui/intrinsics/intrinsic-alignment.rs
+++ b/tests/ui/intrinsics/intrinsic-alignment.rs
@@ -1,14 +1,8 @@
 //@ run-pass
 
-#![feature(intrinsics, rustc_attrs)]
+#![feature(core_intrinsics, rustc_attrs)]
 
-mod rusti {
-    extern "rust-intrinsic" {
-        pub fn pref_align_of<T>() -> usize;
-        #[rustc_safe_intrinsic]
-        pub fn min_align_of<T>() -> usize;
-    }
-}
+use std::intrinsics as rusti;
 
 #[cfg(any(
     target_os = "android",
diff --git a/tests/ui/intrinsics/intrinsics-integer.rs b/tests/ui/intrinsics/intrinsics-integer.rs
index 7dbc4b8b7ce..8eb03924feb 100644
--- a/tests/ui/intrinsics/intrinsics-integer.rs
+++ b/tests/ui/intrinsics/intrinsics-integer.rs
@@ -1,24 +1,8 @@
 //@ run-pass
 
-#![feature(intrinsics)]
-#![feature(rustc_attrs)]
-
-mod rusti {
-    extern "rust-intrinsic" {
-        #[rustc_safe_intrinsic]
-        pub fn ctpop<T>(x: T) -> u32;
-        #[rustc_safe_intrinsic]
-        pub fn ctlz<T>(x: T) -> u32;
-        pub fn ctlz_nonzero<T>(x: T) -> u32;
-        #[rustc_safe_intrinsic]
-        pub fn cttz<T>(x: T) -> u32;
-        pub fn cttz_nonzero<T>(x: T) -> u32;
-        #[rustc_safe_intrinsic]
-        pub fn bswap<T>(x: T) -> T;
-        #[rustc_safe_intrinsic]
-        pub fn bitreverse<T>(x: T) -> T;
-    }
-}
+#![feature(core_intrinsics)]
+
+use std::intrinsics as rusti;
 
 pub fn main() {
     use rusti::*;
diff --git a/tests/ui/intrinsics/not-overridden.rs b/tests/ui/intrinsics/not-overridden.rs
index e1f1bbe0951..16f8e9bcf6a 100644
--- a/tests/ui/intrinsics/not-overridden.rs
+++ b/tests/ui/intrinsics/not-overridden.rs
@@ -1,6 +1,6 @@
 //! Check that intrinsics that do not get overridden, but are marked as such,
 //! cause an error instead of silently invoking the body.
-#![feature(rustc_attrs)]
+#![feature(intrinsics)]
 //@ build-fail
 //@ failure-status:101
 //@ normalize-stderr-test: ".*note: .*\n\n" -> ""
diff --git a/tests/ui/structs-enums/rec-align-u32.rs b/tests/ui/structs-enums/rec-align-u32.rs
index 9cd2a988871..44879189739 100644
--- a/tests/ui/structs-enums/rec-align-u32.rs
+++ b/tests/ui/structs-enums/rec-align-u32.rs
@@ -3,17 +3,10 @@
 #![allow(unused_unsafe)]
 // Issue #2303
 
-#![feature(intrinsics, rustc_attrs)]
+#![feature(core_intrinsics, rustc_attrs)]
 
 use std::mem;
-
-mod rusti {
-    extern "rust-intrinsic" {
-        pub fn pref_align_of<T>() -> usize;
-        #[rustc_safe_intrinsic]
-        pub fn min_align_of<T>() -> usize;
-    }
-}
+use std::intrinsics;
 
 // This is the type with the questionable alignment
 #[derive(Debug)]
@@ -41,12 +34,12 @@ pub fn main() {
         // Send it through the shape code
         let y = format!("{:?}", x);
 
-        println!("align inner = {:?}", rusti::min_align_of::<Inner>());
+        println!("align inner = {:?}", intrinsics::min_align_of::<Inner>());
         println!("size outer = {:?}", mem::size_of::<Outer>());
         println!("y = {:?}", y);
 
         // per clang/gcc the alignment of `inner` is 4 on x86.
-        assert_eq!(rusti::min_align_of::<Inner>(), m::align());
+        assert_eq!(intrinsics::min_align_of::<Inner>(), m::align());
 
         // per clang/gcc the size of `outer` should be 12
         // because `inner`s alignment was 4.
diff --git a/tests/ui/structs-enums/rec-align-u64.rs b/tests/ui/structs-enums/rec-align-u64.rs
index 313ce6d578d..8b501ea5509 100644
--- a/tests/ui/structs-enums/rec-align-u64.rs
+++ b/tests/ui/structs-enums/rec-align-u64.rs
@@ -4,17 +4,10 @@
 
 // Issue #2303
 
-#![feature(intrinsics, rustc_attrs)]
+#![feature(core_intrinsics, rustc_attrs)]
 
 use std::mem;
-
-mod rusti {
-    extern "rust-intrinsic" {
-        pub fn pref_align_of<T>() -> usize;
-        #[rustc_safe_intrinsic]
-        pub fn min_align_of<T>() -> usize;
-    }
-}
+use std::intrinsics;
 
 // This is the type with the questionable alignment
 #[derive(Debug)]
@@ -90,12 +83,12 @@ pub fn main() {
 
         let y = format!("{:?}", x);
 
-        println!("align inner = {:?}", rusti::min_align_of::<Inner>());
+        println!("align inner = {:?}", intrinsics::min_align_of::<Inner>());
         println!("size outer = {:?}", mem::size_of::<Outer>());
         println!("y = {:?}", y);
 
         // per clang/gcc the alignment of `Inner` is 4 on x86.
-        assert_eq!(rusti::min_align_of::<Inner>(), m::m::align());
+        assert_eq!(intrinsics::min_align_of::<Inner>(), m::m::align());
 
         // per clang/gcc the size of `Outer` should be 12
         // because `Inner`s alignment was 4.