about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2021-04-22 18:14:42 +0200
committerGitHub <noreply@github.com>2021-04-22 18:14:42 +0200
commitf180c1e05de9729bd34716418e6adce6e9f649f1 (patch)
tree4febc65e428e9413ff0586054e3205391276d6e1
parentaac5125da4c8f06de57ab89985a5fc204c122483 (diff)
parent75732dd00e845ed27e6a482db965e673805d85a9 (diff)
downloadrust-f180c1e05de9729bd34716418e6adce6e9f649f1.tar.gz
rust-f180c1e05de9729bd34716418e6adce6e9f649f1.zip
Rollup merge of #84404 - tmiasko:intrinsics-in-coercion-lub, r=Mark-Simulacrum
Check for intrinsics before coercing to a function pointer

Return an error if coercing function items / non-capturing closures
to a common function pointer type would require reifying an intrinsic.

Turns ICE reported in #84297 into a proper error.
-rw-r--r--compiler/rustc_typeck/src/check/coercion.rs8
-rw-r--r--src/test/ui/reify-intrinsic.rs8
-rw-r--r--src/test/ui/reify-intrinsic.stderr11
3 files changed, 26 insertions, 1 deletions
diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index fd7c50e9788..427f967a9b6 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -973,6 +973,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         };
         if let (Some(a_sig), Some(b_sig)) = (a_sig, b_sig) {
+            // Intrinsics are not coercible to function pointers.
+            if a_sig.abi() == Abi::RustIntrinsic
+                || a_sig.abi() == Abi::PlatformIntrinsic
+                || b_sig.abi() == Abi::RustIntrinsic
+                || b_sig.abi() == Abi::PlatformIntrinsic
+            {
+                return Err(TypeError::IntrinsicCast);
+            }
             // The signature must match.
             let a_sig = self.normalize_associated_types_in(new.span, a_sig);
             let b_sig = self.normalize_associated_types_in(new.span, b_sig);
diff --git a/src/test/ui/reify-intrinsic.rs b/src/test/ui/reify-intrinsic.rs
index 09baa059e55..05535b92cca 100644
--- a/src/test/ui/reify-intrinsic.rs
+++ b/src/test/ui/reify-intrinsic.rs
@@ -12,4 +12,12 @@ fn b() {
     //~^ ERROR casting
 }
 
+fn c() {
+    let _ = [
+        std::intrinsics::copy_nonoverlapping::<i32>,
+        std::intrinsics::copy::<i32>,
+        //~^ ERROR cannot coerce
+    ];
+}
+
 fn main() {}
diff --git a/src/test/ui/reify-intrinsic.stderr b/src/test/ui/reify-intrinsic.stderr
index 675447f9721..5d82fdbd311 100644
--- a/src/test/ui/reify-intrinsic.stderr
+++ b/src/test/ui/reify-intrinsic.stderr
@@ -19,7 +19,16 @@ error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {transmute::<_,
 LL |     let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0308]: cannot coerce intrinsics to function pointers
+  --> $DIR/reify-intrinsic.rs:18:9
+   |
+LL |         std::intrinsics::copy::<i32>,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot coerce intrinsics to function pointers
+   |
+   = note: expected type `unsafe extern "rust-intrinsic" fn(_, _, _) {copy_nonoverlapping::<i32>}`
+           found fn item `unsafe extern "rust-intrinsic" fn(_, _, _) {std::intrinsics::copy::<i32>}`
+
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0308, E0606.
 For more information about an error, try `rustc --explain E0308`.