diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 4da45303d1277..3b64517089b96 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -55,7 +55,6 @@ use rustc_span::source_map::Spanned;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
-use rustc_target::spec::abi::Abi::RustIntrinsic;
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::ObligationCtxt;
@@ -541,16 +540,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if let ty::FnDef(did, _) = *ty.kind() {
             let fn_sig = ty.fn_sig(tcx);
 
-            if tcx.fn_sig(did).skip_binder().abi() == RustIntrinsic
-                && tcx.item_name(did) == sym::transmute
-            {
+            if tcx.is_intrinsic(did, sym::transmute) {
                 let Some(from) = fn_sig.inputs().skip_binder().get(0) else {
-                    let e = self.dcx().span_delayed_bug(
+                    span_bug!(
                         tcx.def_span(did),
-                        "intrinsic fn `transmute` defined with no parameters",
+                        "intrinsic fn `transmute` defined with no parameters"
                     );
-                    self.set_tainted_by_errors(e);
-                    return Ty::new_error(tcx, e);
                 };
                 let to = fn_sig.output().skip_binder();
                 // We defer the transmute to the end of typeck, once all inference vars have
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index cef15b29a8514..a504212d57859 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -1679,10 +1679,15 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
         .any(|items| items.iter().any(|item| item.has_name(sym::notable_trait)))
 }
 
-/// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute)
+/// Determines whether an item is an intrinsic (which may be via Abi or via the `rustc_intrinsic` attribute).
+///
+/// We double check the feature gate here because whether a function may be defined as an intrinsic causes
+/// 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(), Abi::RustIntrinsic)
-        || tcx.has_attr(def_id, sym::rustc_intrinsic)
+    if (matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic)
+        && tcx.features().intrinsics)
+        || (tcx.has_attr(def_id, sym::rustc_intrinsic) && tcx.features().rustc_attrs)
     {
         Some(ty::IntrinsicDef {
             name: tcx.item_name(def_id.into()),
diff --git a/tests/ui/feature-gates/feature-gate-abi.rs b/tests/ui/feature-gates/feature-gate-abi.rs
index 1c3a732a497fa..3aa430e736f09 100644
--- a/tests/ui/feature-gates/feature-gate-abi.rs
+++ b/tests/ui/feature-gates/feature-gate-abi.rs
@@ -13,10 +13,8 @@ trait Tuple { }
 // Functions
 extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
                                    //~^ ERROR intrinsic must be in
-                                   //~| ERROR unrecognized intrinsic function: `f1`
 extern "rust-intrinsic" fn f2() {} //~ ERROR intrinsics are subject to change
                                        //~^ ERROR intrinsic must be in
-                                       //~| ERROR unrecognized intrinsic function: `f2`
 extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change
 
 // Methods in trait definition
diff --git a/tests/ui/feature-gates/feature-gate-abi.stderr b/tests/ui/feature-gates/feature-gate-abi.stderr
index c28cd05a96ad6..dbdfa7b275d49 100644
--- a/tests/ui/feature-gates/feature-gate-abi.stderr
+++ b/tests/ui/feature-gates/feature-gate-abi.stderr
@@ -8,7 +8,7 @@ LL | extern "rust-intrinsic" fn f1() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:17:8
+  --> $DIR/feature-gate-abi.rs:16:8
    |
 LL | extern "rust-intrinsic" fn f2() {}
    |        ^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL | extern "rust-intrinsic" fn f2() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:20:8
+  --> $DIR/feature-gate-abi.rs:18:8
    |
 LL | extern "rust-call" fn f4(_: ()) {}
    |        ^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL | extern "rust-call" fn f4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:24:12
+  --> $DIR/feature-gate-abi.rs:22:12
    |
 LL |     extern "rust-intrinsic" fn m1();
    |            ^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL |     extern "rust-intrinsic" fn m1();
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:26:12
+  --> $DIR/feature-gate-abi.rs:24:12
    |
 LL |     extern "rust-intrinsic" fn m2();
    |            ^^^^^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL |     extern "rust-intrinsic" fn m2();
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:28:12
+  --> $DIR/feature-gate-abi.rs:26:12
    |
 LL |     extern "rust-call" fn m4(_: ());
    |            ^^^^^^^^^^^
@@ -55,7 +55,7 @@ LL |     extern "rust-call" fn m4(_: ());
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:30:12
+  --> $DIR/feature-gate-abi.rs:28:12
    |
 LL |     extern "rust-call" fn dm4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -65,7 +65,7 @@ LL |     extern "rust-call" fn dm4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:37:12
+  --> $DIR/feature-gate-abi.rs:35:12
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -74,7 +74,7 @@ LL |     extern "rust-intrinsic" fn m1() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:39:12
+  --> $DIR/feature-gate-abi.rs:37:12
    |
 LL |     extern "rust-intrinsic" fn m2() {}
    |            ^^^^^^^^^^^^^^^^
@@ -83,7 +83,7 @@ LL |     extern "rust-intrinsic" fn m2() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:41:12
+  --> $DIR/feature-gate-abi.rs:39:12
    |
 LL |     extern "rust-call" fn m4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -93,7 +93,7 @@ LL |     extern "rust-call" fn m4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:46:12
+  --> $DIR/feature-gate-abi.rs:44:12
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -102,7 +102,7 @@ LL |     extern "rust-intrinsic" fn im1() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:48:12
+  --> $DIR/feature-gate-abi.rs:46:12
    |
 LL |     extern "rust-intrinsic" fn im2() {}
    |            ^^^^^^^^^^^^^^^^
@@ -111,7 +111,7 @@ LL |     extern "rust-intrinsic" fn im2() {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:50:12
+  --> $DIR/feature-gate-abi.rs:48:12
    |
 LL |     extern "rust-call" fn im4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL |     extern "rust-call" fn im4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:54:18
+  --> $DIR/feature-gate-abi.rs:52:18
    |
 LL | type A1 = extern "rust-intrinsic" fn();
    |                  ^^^^^^^^^^^^^^^^
@@ -130,7 +130,7 @@ LL | type A1 = extern "rust-intrinsic" fn();
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:55:18
+  --> $DIR/feature-gate-abi.rs:53:18
    |
 LL | type A2 = extern "rust-intrinsic" fn();
    |                  ^^^^^^^^^^^^^^^^
@@ -139,7 +139,7 @@ LL | type A2 = extern "rust-intrinsic" fn();
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:56:18
+  --> $DIR/feature-gate-abi.rs:54:18
    |
 LL | type A4 = extern "rust-call" fn(_: ());
    |                  ^^^^^^^^^^^
@@ -149,7 +149,7 @@ LL | type A4 = extern "rust-call" fn(_: ());
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:59:8
+  --> $DIR/feature-gate-abi.rs:57:8
    |
 LL | extern "rust-intrinsic" {}
    |        ^^^^^^^^^^^^^^^^
@@ -158,7 +158,7 @@ LL | extern "rust-intrinsic" {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:60:8
+  --> $DIR/feature-gate-abi.rs:58:8
    |
 LL | extern "rust-intrinsic" {}
    |        ^^^^^^^^^^^^^^^^
@@ -167,7 +167,7 @@ LL | extern "rust-intrinsic" {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:61:8
+  --> $DIR/feature-gate-abi.rs:59:8
    |
 LL | extern "rust-call" {}
    |        ^^^^^^^^^^^
@@ -176,30 +176,14 @@ LL | extern "rust-call" {}
    = help: add `#![feature(unboxed_closures)]` 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[E0093]: unrecognized intrinsic function: `f1`
-  --> $DIR/feature-gate-abi.rs:14:28
-   |
-LL | extern "rust-intrinsic" fn f1() {}
-   |                            ^^ unrecognized intrinsic
-   |
-   = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type`
-
-error[E0093]: unrecognized intrinsic function: `f2`
-  --> $DIR/feature-gate-abi.rs:17:28
-   |
-LL | extern "rust-intrinsic" fn f2() {}
-   |                            ^^ unrecognized intrinsic
-   |
-   = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type`
-
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:24:32
+  --> $DIR/feature-gate-abi.rs:22:32
    |
 LL |     extern "rust-intrinsic" fn m1();
    |                                ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:26:32
+  --> $DIR/feature-gate-abi.rs:24:32
    |
 LL |     extern "rust-intrinsic" fn m2();
    |                                ^^
@@ -211,36 +195,35 @@ LL | extern "rust-intrinsic" fn f1() {}
    |                                 ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:17:33
+  --> $DIR/feature-gate-abi.rs:16:33
    |
 LL | extern "rust-intrinsic" fn f2() {}
    |                                 ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:37:37
+  --> $DIR/feature-gate-abi.rs:35:37
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:39:37
+  --> $DIR/feature-gate-abi.rs:37:37
    |
 LL |     extern "rust-intrinsic" fn m2() {}
    |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:46:38
+  --> $DIR/feature-gate-abi.rs:44:38
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |                                      ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:48:38
+  --> $DIR/feature-gate-abi.rs:46:38
    |
 LL |     extern "rust-intrinsic" fn im2() {}
    |                                      ^^
 
-error: aborting due to 29 previous errors
+error: aborting due to 27 previous errors
 
-Some errors have detailed explanations: E0093, E0658.
-For more information about an error, try `rustc --explain E0093`.
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.rs b/tests/ui/feature-gates/feature-gate-intrinsics.rs
index 725d968d24c30..e0dc3cc579d79 100644
--- a/tests/ui/feature-gates/feature-gate-intrinsics.rs
+++ b/tests/ui/feature-gates/feature-gate-intrinsics.rs
@@ -4,6 +4,5 @@ extern "rust-intrinsic" {   //~ ERROR intrinsics are subject to change
 
 extern "rust-intrinsic" fn baz() {} //~ ERROR intrinsics are subject to change
 //~^ ERROR intrinsic must be in
-//~| ERROR unrecognized intrinsic function: `baz`
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-intrinsics.stderr b/tests/ui/feature-gates/feature-gate-intrinsics.stderr
index 583a4a1a84eb0..577a620e2d2c5 100644
--- a/tests/ui/feature-gates/feature-gate-intrinsics.stderr
+++ b/tests/ui/feature-gates/feature-gate-intrinsics.stderr
@@ -24,21 +24,13 @@ LL |     fn bar();
    |
    = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type`
 
-error[E0093]: unrecognized intrinsic function: `baz`
-  --> $DIR/feature-gate-intrinsics.rs:5:28
-   |
-LL | extern "rust-intrinsic" fn baz() {}
-   |                            ^^^ unrecognized intrinsic
-   |
-   = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type`
-
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
   --> $DIR/feature-gate-intrinsics.rs:5:34
    |
 LL | extern "rust-intrinsic" fn baz() {}
    |                                  ^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0093, E0658.
 For more information about an error, try `rustc --explain E0093`.
diff --git a/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs b/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs
new file mode 100644
index 0000000000000..66de1f60ed9bc
--- /dev/null
+++ b/tests/ui/intrinsics/incorrect-read_via_copy-defn.rs
@@ -0,0 +1,7 @@
+fn main() {
+    read_via_copy();
+}
+
+extern "rust-intrinsic" fn read_via_copy() {}
+//~^ ERROR intrinsics are subject to change
+//~| ERROR intrinsic must be in `extern "rust-intrinsic" { ... }` block
diff --git a/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr b/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr
new file mode 100644
index 0000000000000..362ee185b7b17
--- /dev/null
+++ b/tests/ui/intrinsics/incorrect-read_via_copy-defn.stderr
@@ -0,0 +1,18 @@
+error[E0658]: intrinsics are subject to change
+  --> $DIR/incorrect-read_via_copy-defn.rs:5:8
+   |
+LL | extern "rust-intrinsic" fn read_via_copy() {}
+   |        ^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(intrinsics)]` 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: intrinsic must be in `extern "rust-intrinsic" { ... }` block
+  --> $DIR/incorrect-read_via_copy-defn.rs:5:44
+   |
+LL | extern "rust-intrinsic" fn read_via_copy() {}
+   |                                            ^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/intrinsics/incorrect-transmute.rs b/tests/ui/intrinsics/incorrect-transmute.rs
index 4f1d1491ec9c2..eed524ae8a8a2 100644
--- a/tests/ui/intrinsics/incorrect-transmute.rs
+++ b/tests/ui/intrinsics/incorrect-transmute.rs
@@ -3,6 +3,5 @@ fn main() {
 }
 
 extern "rust-intrinsic" fn transmute() {}
-//~^ ERROR intrinsic has wrong number of type parameters: found 0, expected 2
-//~| ERROR intrinsics are subject to change
+//~^ ERROR intrinsics are subject to change
 //~| ERROR intrinsic must be in `extern "rust-intrinsic" { ... }` block
diff --git a/tests/ui/intrinsics/incorrect-transmute.stderr b/tests/ui/intrinsics/incorrect-transmute.stderr
index 20b95925b76d0..8123f3d71a295 100644
--- a/tests/ui/intrinsics/incorrect-transmute.stderr
+++ b/tests/ui/intrinsics/incorrect-transmute.stderr
@@ -7,19 +7,12 @@ LL | extern "rust-intrinsic" fn transmute() {}
    = help: add `#![feature(intrinsics)]` 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[E0094]: intrinsic has wrong number of type parameters: found 0, expected 2
-  --> $DIR/incorrect-transmute.rs:5:37
-   |
-LL | extern "rust-intrinsic" fn transmute() {}
-   |                                     ^ expected 2 type parameters
-
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
   --> $DIR/incorrect-transmute.rs:5:40
    |
 LL | extern "rust-intrinsic" fn transmute() {}
    |                                        ^^
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0094, E0658.
-For more information about an error, try `rustc --explain E0094`.
+For more information about this error, try `rustc --explain E0658`.