summaryrefslogtreecommitdiffstats
path: root/tests/ui/intrinsics
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/intrinsics')
-rw-r--r--tests/ui/intrinsics/auxiliary/cci_intrinsic.rs14
-rw-r--r--tests/ui/intrinsics/bad-intrinsic-monomorphization.rs32
-rw-r--r--tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr21
-rw-r--r--tests/ui/intrinsics/const-eval-select-backtrace-std.rs7
-rw-r--r--tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr2
-rw-r--r--tests/ui/intrinsics/const-eval-select-backtrace.rs19
-rw-r--r--tests/ui/intrinsics/const-eval-select-backtrace.run.stderr2
-rw-r--r--tests/ui/intrinsics/const-eval-select-bad.rs46
-rw-r--r--tests/ui/intrinsics/const-eval-select-bad.stderr101
-rw-r--r--tests/ui/intrinsics/const-eval-select-stability.rs21
-rw-r--r--tests/ui/intrinsics/const-eval-select-stability.stderr10
-rw-r--r--tests/ui/intrinsics/const-eval-select-x86_64.rs40
-rw-r--r--tests/ui/intrinsics/const-eval-select.rs27
-rw-r--r--tests/ui/intrinsics/intrinsic-alignment.rs67
-rw-r--r--tests/ui/intrinsics/intrinsic-assume.rs17
-rw-r--r--tests/ui/intrinsics/intrinsic-atomics-cc.rs12
-rw-r--r--tests/ui/intrinsics/intrinsic-atomics.rs102
-rw-r--r--tests/ui/intrinsics/intrinsic-nearby.rs11
-rw-r--r--tests/ui/intrinsics/intrinsic-raw_eq-const-padding.rs10
-rw-r--r--tests/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr9
-rw-r--r--tests/ui/intrinsics/intrinsic-raw_eq-const.rs26
-rw-r--r--tests/ui/intrinsics/intrinsic-unreachable.rs17
-rw-r--r--tests/ui/intrinsics/intrinsic-volatile.rs44
-rw-r--r--tests/ui/intrinsics/intrinsics-integer.rs177
-rw-r--r--tests/ui/intrinsics/intrinsics-math.rs60
-rw-r--r--tests/ui/intrinsics/issue-28575.mir.stderr11
-rw-r--r--tests/ui/intrinsics/issue-28575.rs12
-rw-r--r--tests/ui/intrinsics/issue-28575.thir.stderr11
-rw-r--r--tests/ui/intrinsics/issue-84297-reifying-copy.rs9
-rw-r--r--tests/ui/intrinsics/non-integer-atomic.rs92
-rw-r--r--tests/ui/intrinsics/non-integer-atomic.stderr99
-rw-r--r--tests/ui/intrinsics/panic-uninitialized-zeroed.rs397
-rw-r--r--tests/ui/intrinsics/safe-intrinsic-mismatch.rs11
-rw-r--r--tests/ui/intrinsics/safe-intrinsic-mismatch.stderr14
-rw-r--r--tests/ui/intrinsics/unchecked_math_unsafe.mir.stderr27
-rw-r--r--tests/ui/intrinsics/unchecked_math_unsafe.rs11
-rw-r--r--tests/ui/intrinsics/unchecked_math_unsafe.thir.stderr27
-rw-r--r--tests/ui/intrinsics/unchecked_math_unstable.rs8
-rw-r--r--tests/ui/intrinsics/unchecked_math_unstable.stderr27
39 files changed, 1650 insertions, 0 deletions
diff --git a/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs
new file mode 100644
index 000000000..f3b9d569c
--- /dev/null
+++ b/tests/ui/intrinsics/auxiliary/cci_intrinsic.rs
@@ -0,0 +1,14 @@
+#![feature(intrinsics)]
+
+pub mod rusti {
+ extern "rust-intrinsic" {
+ pub fn atomic_xchg_seqcst<T>(dst: *mut T, src: T) -> T;
+ }
+}
+
+#[inline(always)]
+pub fn atomic_xchg_seqcst(dst: *mut isize, src: isize) -> isize {
+ unsafe {
+ rusti::atomic_xchg_seqcst(dst, src)
+ }
+}
diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs
new file mode 100644
index 000000000..f36a5f1ac
--- /dev/null
+++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs
@@ -0,0 +1,32 @@
+// build-fail
+
+#![feature(repr_simd, platform_intrinsics, core_intrinsics)]
+#![allow(warnings)]
+#![crate_type = "rlib"]
+
+// Bad monomorphizations could previously cause LLVM asserts even though the
+// error was caught in the compiler.
+
+extern "platform-intrinsic" {
+ fn simd_add<T>(x: T, y: T) -> T;
+}
+
+use std::intrinsics;
+
+#[derive(Copy, Clone)]
+pub struct Foo(i64);
+
+pub fn test_cttz(v: Foo) -> Foo {
+ intrinsics::cttz(v)
+ //~^ ERROR `cttz` intrinsic: expected basic integer type, found `Foo`
+}
+
+pub unsafe fn test_fadd_fast(a: Foo, b: Foo) -> Foo {
+ intrinsics::fadd_fast(a, b)
+ //~^ ERROR `fadd_fast` intrinsic: expected basic float type, found `Foo`
+}
+
+pub unsafe fn test_simd_add(a: Foo, b: Foo) -> Foo {
+ simd_add(a, b)
+ //~^ ERROR `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo`
+}
diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr
new file mode 100644
index 000000000..c070f0181
--- /dev/null
+++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.stderr
@@ -0,0 +1,21 @@
+error[E0511]: invalid monomorphization of `cttz` intrinsic: expected basic integer type, found `Foo`
+ --> $DIR/bad-intrinsic-monomorphization.rs:20:5
+ |
+LL | intrinsics::cttz(v)
+ | ^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `fadd_fast` intrinsic: expected basic float type, found `Foo`
+ --> $DIR/bad-intrinsic-monomorphization.rs:25:5
+ |
+LL | intrinsics::fadd_fast(a, b)
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_add` intrinsic: expected SIMD input type, found non-SIMD `Foo`
+ --> $DIR/bad-intrinsic-monomorphization.rs:30:5
+ |
+LL | simd_add(a, b)
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/tests/ui/intrinsics/const-eval-select-backtrace-std.rs b/tests/ui/intrinsics/const-eval-select-backtrace-std.rs
new file mode 100644
index 000000000..1164a3a5b
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select-backtrace-std.rs
@@ -0,0 +1,7 @@
+// See issue #100696.
+// run-fail
+// check-run-results
+// exec-env:RUST_BACKTRACE=0
+fn main() {
+ &""[1..];
+}
diff --git a/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
new file mode 100644
index 000000000..463cd52c5
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
@@ -0,0 +1,2 @@
+thread 'main' panicked at 'byte index 1 is out of bounds of ``', $DIR/const-eval-select-backtrace-std.rs:6:6
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/intrinsics/const-eval-select-backtrace.rs b/tests/ui/intrinsics/const-eval-select-backtrace.rs
new file mode 100644
index 000000000..ef1c7c419
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select-backtrace.rs
@@ -0,0 +1,19 @@
+#![feature(core_intrinsics)]
+// See issue #100696.
+// run-fail
+// check-run-results
+// exec-env:RUST_BACKTRACE=0
+
+#[track_caller]
+fn uhoh() {
+ panic!("Aaah!")
+}
+
+const fn c() {}
+
+fn main() {
+ // safety: this is unsound and just used to test
+ unsafe {
+ std::intrinsics::const_eval_select((), c, uhoh);
+ }
+}
diff --git a/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr b/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr
new file mode 100644
index 000000000..54e28db5e
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select-backtrace.run.stderr
@@ -0,0 +1,2 @@
+thread 'main' panicked at 'Aaah!', $DIR/const-eval-select-backtrace.rs:17:9
+note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/intrinsics/const-eval-select-bad.rs b/tests/ui/intrinsics/const-eval-select-bad.rs
new file mode 100644
index 000000000..fa14efad7
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select-bad.rs
@@ -0,0 +1,46 @@
+#![feature(const_eval_select)]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::const_eval_select;
+
+const fn not_fn_items() {
+ const_eval_select((), || {}, || {});
+ //~^ ERROR this argument must be a function item
+ //~| ERROR this argument must be a function item
+ const_eval_select((), 42, 0xDEADBEEF);
+ //~^ ERROR expected a `FnOnce<()>` closure
+ //~| ERROR expected a `FnOnce<()>` closure
+ //~| ERROR this argument must be a function item
+ //~| ERROR this argument must be a function item
+}
+
+const fn foo(n: i32) -> i32 {
+ n
+}
+
+fn bar(n: i32) -> bool {
+ assert_eq!(n, 0, "{} must be equal to {}", n, 0);
+ n == 0
+}
+
+fn baz(n: bool) -> i32 {
+ assert!(n, "{} must be true", n);
+ n as i32
+}
+
+const fn return_ty_mismatch() {
+ const_eval_select((1,), foo, bar);
+ //~^ ERROR expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
+}
+
+const fn args_ty_mismatch() {
+ const_eval_select((true,), foo, baz);
+ //~^ ERROR type mismatch
+}
+
+const fn non_const_fn() {
+ const_eval_select((1,), bar, bar);
+ //~^ ERROR this argument must be a `const fn`
+}
+
+fn main() {}
diff --git a/tests/ui/intrinsics/const-eval-select-bad.stderr b/tests/ui/intrinsics/const-eval-select-bad.stderr
new file mode 100644
index 000000000..fd7d061b6
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select-bad.stderr
@@ -0,0 +1,101 @@
+error: this argument must be a function item
+ --> $DIR/const-eval-select-bad.rs:7:27
+ |
+LL | const_eval_select((), || {}, || {});
+ | ^^^^^
+ |
+ = note: expected a function item, found [closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]
+ = help: consult the documentation on `const_eval_select` for more information
+
+error: this argument must be a function item
+ --> $DIR/const-eval-select-bad.rs:7:34
+ |
+LL | const_eval_select((), || {}, || {});
+ | ^^^^^
+ |
+ = note: expected a function item, found [closure@$DIR/const-eval-select-bad.rs:7:34: 7:36]
+ = help: consult the documentation on `const_eval_select` for more information
+
+error: this argument must be a function item
+ --> $DIR/const-eval-select-bad.rs:10:27
+ |
+LL | const_eval_select((), 42, 0xDEADBEEF);
+ | ^^
+ |
+ = note: expected a function item, found {integer}
+ = help: consult the documentation on `const_eval_select` for more information
+
+error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
+ --> $DIR/const-eval-select-bad.rs:10:27
+ |
+LL | const_eval_select((), 42, 0xDEADBEEF);
+ | ----------------- ^^ expected an `FnOnce<()>` closure, found `{integer}`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `FnOnce<()>` is not implemented for `{integer}`
+ = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }`
+note: required by a bound in `const_eval_select`
+ --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+
+error: this argument must be a function item
+ --> $DIR/const-eval-select-bad.rs:10:31
+ |
+LL | const_eval_select((), 42, 0xDEADBEEF);
+ | ^^^^^^^^^^
+ |
+ = note: expected a function item, found {integer}
+ = help: consult the documentation on `const_eval_select` for more information
+
+error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
+ --> $DIR/const-eval-select-bad.rs:10:31
+ |
+LL | const_eval_select((), 42, 0xDEADBEEF);
+ | ----------------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}`
+ | |
+ | required by a bound introduced by this call
+ |
+ = help: the trait `FnOnce<()>` is not implemented for `{integer}`
+ = note: wrap the `{integer}` in a closure with no arguments: `|| { /* code */ }`
+note: required by a bound in `const_eval_select`
+ --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+
+error[E0271]: expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
+ --> $DIR/const-eval-select-bad.rs:32:34
+ |
+LL | const_eval_select((1,), foo, bar);
+ | ----------------- ^^^ expected `i32`, found `bool`
+ | |
+ | required by a bound introduced by this call
+ |
+note: required by a bound in `const_eval_select`
+ --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+
+error[E0631]: type mismatch in function arguments
+ --> $DIR/const-eval-select-bad.rs:37:32
+ |
+LL | const fn foo(n: i32) -> i32 {
+ | --------------------------- found signature defined here
+...
+LL | const_eval_select((true,), foo, baz);
+ | ----------------- ^^^ expected due to this
+ | |
+ | required by a bound introduced by this call
+ |
+ = note: expected function signature `fn(bool) -> _`
+ found function signature `fn(i32) -> _`
+note: required by a bound in `const_eval_select`
+ --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+
+error: this argument must be a `const fn`
+ --> $DIR/const-eval-select-bad.rs:42:29
+ |
+LL | const_eval_select((1,), bar, bar);
+ | ^^^
+ |
+ = help: consult the documentation on `const_eval_select` for more information
+
+error: aborting due to 9 previous errors
+
+Some errors have detailed explanations: E0271, E0277, E0631.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/intrinsics/const-eval-select-stability.rs b/tests/ui/intrinsics/const-eval-select-stability.rs
new file mode 100644
index 000000000..f9554dece
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select-stability.rs
@@ -0,0 +1,21 @@
+#![feature(staged_api)]
+#![feature(const_eval_select)]
+#![feature(core_intrinsics)]
+#![stable(since = "1.0", feature = "ui_test")]
+
+use std::intrinsics::const_eval_select;
+
+fn log() {
+ println!("HEY HEY HEY")
+}
+
+const fn nothing(){}
+
+#[stable(since = "1.0", feature = "hey")]
+#[rustc_const_stable(since = "1.0", feature = "const_hey")]
+pub const unsafe fn hey() {
+ const_eval_select((), nothing, log);
+ //~^ ERROR `const_eval_select` is not yet stable as a const fn
+}
+
+fn main() {}
diff --git a/tests/ui/intrinsics/const-eval-select-stability.stderr b/tests/ui/intrinsics/const-eval-select-stability.stderr
new file mode 100644
index 000000000..65b507b88
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select-stability.stderr
@@ -0,0 +1,10 @@
+error: `const_eval_select` is not yet stable as a const fn
+ --> $DIR/const-eval-select-stability.rs:17:5
+ |
+LL | const_eval_select((), nothing, log);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: const-stable functions can only call other const-stable functions
+
+error: aborting due to previous error
+
diff --git a/tests/ui/intrinsics/const-eval-select-x86_64.rs b/tests/ui/intrinsics/const-eval-select-x86_64.rs
new file mode 100644
index 000000000..f3924acf0
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select-x86_64.rs
@@ -0,0 +1,40 @@
+// run-pass
+// only-x86_64
+
+#![feature(const_eval_select)]
+#![feature(core_intrinsics)]
+use std::intrinsics::const_eval_select;
+use std::arch::x86_64::*;
+use std::mem::transmute;
+
+const fn eq_ct(x: [i32; 4], y: [i32; 4]) -> bool {
+ x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3]
+}
+
+fn eq_rt(x: [i32; 4], y: [i32; 4]) -> bool {
+ unsafe {
+ let x = _mm_loadu_si128(&x as *const _ as *const _);
+ let y = _mm_loadu_si128(&y as *const _ as *const _);
+ let r = _mm_cmpeq_epi32(x, y);
+ let r = _mm_movemask_ps(transmute(r) );
+ r == 0b1111
+ }
+}
+
+const fn eq(x: [i32; 4], y: [i32; 4]) -> bool {
+ unsafe {
+ const_eval_select((x, y), eq_ct, eq_rt)
+ }
+}
+
+fn main() {
+ const X: bool = eq([0, 1, 2, 3], [0, 1, 2, 3]);
+ assert_eq!(X, true);
+ let x = eq([0, 1, 2, 3], [0, 1, 2, 3]);
+ assert_eq!(x, true);
+
+ const Y: bool = eq([0, 1, 2, 3], [0, 1, 3, 2]);
+ assert_eq!(Y, false);
+ let y = eq([0, 1, 2, 3], [0, 1, 3, 2]);
+ assert_eq!(y, false);
+}
diff --git a/tests/ui/intrinsics/const-eval-select.rs b/tests/ui/intrinsics/const-eval-select.rs
new file mode 100644
index 000000000..9ff20d3fb
--- /dev/null
+++ b/tests/ui/intrinsics/const-eval-select.rs
@@ -0,0 +1,27 @@
+// run-pass
+
+#![feature(const_eval_select)]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::const_eval_select;
+
+const fn yes() -> bool {
+ true
+}
+
+fn no() -> bool {
+ false
+}
+
+// not a sound use case; testing only
+const fn is_const_eval() -> bool {
+ unsafe { const_eval_select((), yes, no) }
+}
+
+fn main() {
+ const YES: bool = is_const_eval();
+ let no = is_const_eval();
+
+ assert_eq!(true, YES);
+ assert_eq!(false, no);
+}
diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs
new file mode 100644
index 000000000..c8b1ff1db
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-alignment.rs
@@ -0,0 +1,67 @@
+// run-pass
+// ignore-wasm32-bare seems not important to test here
+
+#![feature(intrinsics)]
+
+mod rusti {
+ extern "rust-intrinsic" {
+ pub fn pref_align_of<T>() -> usize;
+ #[rustc_safe_intrinsic]
+ pub fn min_align_of<T>() -> usize;
+ }
+}
+
+#[cfg(any(target_os = "android",
+ target_os = "dragonfly",
+ target_os = "emscripten",
+ target_os = "freebsd",
+ target_os = "fuchsia",
+ target_os = "illumos",
+ target_os = "linux",
+ target_os = "macos",
+ target_os = "netbsd",
+ target_os = "openbsd",
+ target_os = "solaris",
+ target_os = "vxworks"))]
+mod m {
+ #[cfg(target_arch = "x86")]
+ pub fn main() {
+ unsafe {
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 4);
+ }
+ }
+
+ #[cfg(not(target_arch = "x86"))]
+ pub fn main() {
+ unsafe {
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 8);
+ }
+ }
+}
+
+#[cfg(target_env = "sgx")]
+mod m {
+ #[cfg(target_arch = "x86_64")]
+ pub fn main() {
+ unsafe {
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 8);
+ }
+ }
+}
+
+#[cfg(target_os = "windows")]
+mod m {
+ pub fn main() {
+ unsafe {
+ assert_eq!(::rusti::pref_align_of::<u64>(), 8);
+ assert_eq!(::rusti::min_align_of::<u64>(), 8);
+ }
+ }
+}
+
+fn main() {
+ m::main();
+}
diff --git a/tests/ui/intrinsics/intrinsic-assume.rs b/tests/ui/intrinsics/intrinsic-assume.rs
new file mode 100644
index 000000000..3c9d70cb5
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-assume.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![feature(core_intrinsics)]
+
+use std::intrinsics::assume;
+
+unsafe fn f(x: i32) -> i32 {
+ assume(x == 34);
+ match x {
+ 34 => 42,
+ _ => 30
+ }
+}
+
+fn main() {
+ let x = unsafe { f(34) };
+ assert_eq!(x, 42);
+}
diff --git a/tests/ui/intrinsics/intrinsic-atomics-cc.rs b/tests/ui/intrinsics/intrinsic-atomics-cc.rs
new file mode 100644
index 000000000..ce3fa7b0c
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-atomics-cc.rs
@@ -0,0 +1,12 @@
+// run-pass
+// aux-build:cci_intrinsic.rs
+
+
+extern crate cci_intrinsic;
+use cci_intrinsic::atomic_xchg_seqcst;
+
+pub fn main() {
+ let mut x = 1;
+ atomic_xchg_seqcst(&mut x, 5);
+ assert_eq!(x, 5);
+}
diff --git a/tests/ui/intrinsics/intrinsic-atomics.rs b/tests/ui/intrinsics/intrinsic-atomics.rs
new file mode 100644
index 000000000..b17f4347b
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-atomics.rs
@@ -0,0 +1,102 @@
+// run-pass
+#![feature(intrinsics)]
+
+mod rusti {
+ extern "rust-intrinsic" {
+ pub fn atomic_cxchg_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+ pub fn atomic_cxchg_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+ pub fn atomic_cxchg_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+
+ pub fn atomic_cxchgweak_seqcst_seqcst<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+ pub fn atomic_cxchgweak_acquire_acquire<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+ pub fn atomic_cxchgweak_release_relaxed<T>(dst: *mut T, old: T, src: T) -> (T, bool);
+
+ pub fn atomic_load_seqcst<T>(src: *const T) -> T;
+ pub fn atomic_load_acquire<T>(src: *const T) -> T;
+
+ pub fn atomic_store_seqcst<T>(dst: *mut T, val: T);
+ pub fn atomic_store_release<T>(dst: *mut T, val: T);
+
+ pub fn atomic_xchg_seqcst<T>(dst: *mut T, src: T) -> T;
+ pub fn atomic_xchg_acquire<T>(dst: *mut T, src: T) -> T;
+ pub fn atomic_xchg_release<T>(dst: *mut T, src: T) -> T;
+
+ pub fn atomic_xadd_seqcst<T>(dst: *mut T, src: T) -> T;
+ pub fn atomic_xadd_acquire<T>(dst: *mut T, src: T) -> T;
+ pub fn atomic_xadd_release<T>(dst: *mut T, src: T) -> T;
+
+ pub fn atomic_xsub_seqcst<T>(dst: *mut T, src: T) -> T;
+ pub fn atomic_xsub_acquire<T>(dst: *mut T, src: T) -> T;
+ pub fn atomic_xsub_release<T>(dst: *mut T, src: T) -> T;
+ }
+}
+
+pub fn main() {
+ unsafe {
+ let mut x: Box<_> = Box::new(1);
+
+ assert_eq!(rusti::atomic_load_seqcst(&*x), 1);
+ *x = 5;
+ assert_eq!(rusti::atomic_load_acquire(&*x), 5);
+
+ rusti::atomic_store_seqcst(&mut *x,3);
+ assert_eq!(*x, 3);
+ rusti::atomic_store_release(&mut *x,1);
+ assert_eq!(*x, 1);
+
+ assert_eq!(rusti::atomic_cxchg_seqcst_seqcst(&mut *x, 1, 2), (1, true));
+ assert_eq!(*x, 2);
+
+ assert_eq!(rusti::atomic_cxchg_acquire_acquire(&mut *x, 1, 3), (2, false));
+ assert_eq!(*x, 2);
+
+ assert_eq!(rusti::atomic_cxchg_release_relaxed(&mut *x, 2, 1), (2, true));
+ assert_eq!(*x, 1);
+
+ assert_eq!(rusti::atomic_xchg_seqcst(&mut *x, 0), 1);
+ assert_eq!(*x, 0);
+
+ assert_eq!(rusti::atomic_xchg_acquire(&mut *x, 1), 0);
+ assert_eq!(*x, 1);
+
+ assert_eq!(rusti::atomic_xchg_release(&mut *x, 0), 1);
+ assert_eq!(*x, 0);
+
+ assert_eq!(rusti::atomic_xadd_seqcst(&mut *x, 1), 0);
+ assert_eq!(rusti::atomic_xadd_acquire(&mut *x, 1), 1);
+ assert_eq!(rusti::atomic_xadd_release(&mut *x, 1), 2);
+ assert_eq!(*x, 3);
+
+ assert_eq!(rusti::atomic_xsub_seqcst(&mut *x, 1), 3);
+ assert_eq!(rusti::atomic_xsub_acquire(&mut *x, 1), 2);
+ assert_eq!(rusti::atomic_xsub_release(&mut *x, 1), 1);
+ assert_eq!(*x, 0);
+
+ loop {
+ let res = rusti::atomic_cxchgweak_seqcst_seqcst(&mut *x, 0, 1);
+ assert_eq!(res.0, 0);
+ if res.1 {
+ break;
+ }
+ }
+ assert_eq!(*x, 1);
+
+ loop {
+ let res = rusti::atomic_cxchgweak_acquire_acquire(&mut *x, 1, 2);
+ assert_eq!(res.0, 1);
+ if res.1 {
+ break;
+ }
+ }
+ assert_eq!(*x, 2);
+
+ loop {
+ let res = rusti::atomic_cxchgweak_release_relaxed(&mut *x, 2, 3);
+ assert_eq!(res.0, 2);
+ if res.1 {
+ break;
+ }
+ }
+ assert_eq!(*x, 3);
+ }
+}
diff --git a/tests/ui/intrinsics/intrinsic-nearby.rs b/tests/ui/intrinsics/intrinsic-nearby.rs
new file mode 100644
index 000000000..7b1d1eeaa
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-nearby.rs
@@ -0,0 +1,11 @@
+// run-pass
+#![feature(core_intrinsics)]
+
+use std::intrinsics::*;
+
+fn main() {
+ unsafe {
+ assert_eq!(nearbyintf32(5.234f32), 5f32);
+ assert_eq!(nearbyintf64(6.777f64), 7f64);
+ }
+}
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.rs b/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.rs
new file mode 100644
index 000000000..a93d777d2
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.rs
@@ -0,0 +1,10 @@
+#![feature(core_intrinsics)]
+#![feature(const_intrinsic_raw_eq)]
+
+const BAD_RAW_EQ_CALL: bool = unsafe {
+ std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16))
+//~^ ERROR evaluation of constant value failed
+};
+
+pub fn main() {
+}
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr b/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr
new file mode 100644
index 000000000..56d5a4857
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/intrinsic-raw_eq-const-padding.rs:5:5
+ |
+LL | std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16))
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ reading memory at alloc3[0x0..0x4], but memory is uninitialized at [0x1..0x2], and this operation requires initialized memory
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/intrinsics/intrinsic-raw_eq-const.rs b/tests/ui/intrinsics/intrinsic-raw_eq-const.rs
new file mode 100644
index 000000000..32841f531
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-raw_eq-const.rs
@@ -0,0 +1,26 @@
+// run-pass
+
+#![feature(core_intrinsics)]
+#![feature(const_intrinsic_raw_eq)]
+
+pub fn main() {
+ use std::intrinsics::raw_eq;
+
+ const RAW_EQ_I32_TRUE: bool = unsafe { raw_eq(&42_i32, &42) };
+ assert!(RAW_EQ_I32_TRUE);
+
+ const RAW_EQ_I32_FALSE: bool = unsafe { raw_eq(&4_i32, &2) };
+ assert!(!RAW_EQ_I32_FALSE);
+
+ const RAW_EQ_CHAR_TRUE: bool = unsafe { raw_eq(&'a', &'a') };
+ assert!(RAW_EQ_CHAR_TRUE);
+
+ const RAW_EQ_CHAR_FALSE: bool = unsafe { raw_eq(&'a', &'A') };
+ assert!(!RAW_EQ_CHAR_FALSE);
+
+ const RAW_EQ_ARRAY_TRUE: bool = unsafe { raw_eq(&[13_u8, 42], &[13, 42]) };
+ assert!(RAW_EQ_ARRAY_TRUE);
+
+ const RAW_EQ_ARRAY_FALSE: bool = unsafe { raw_eq(&[13_u8, 42], &[42, 13]) };
+ assert!(!RAW_EQ_ARRAY_FALSE);
+}
diff --git a/tests/ui/intrinsics/intrinsic-unreachable.rs b/tests/ui/intrinsics/intrinsic-unreachable.rs
new file mode 100644
index 000000000..73dd71d48
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-unreachable.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![feature(core_intrinsics)]
+
+use std::intrinsics;
+
+// See also tests/run-make/intrinsic-unreachable.
+
+unsafe fn f(x: usize) -> usize {
+ match x {
+ 17 => 23,
+ _ => intrinsics::unreachable(),
+ }
+}
+
+fn main() {
+ assert_eq!(unsafe { f(17) }, 23);
+}
diff --git a/tests/ui/intrinsics/intrinsic-volatile.rs b/tests/ui/intrinsics/intrinsic-volatile.rs
new file mode 100644
index 000000000..7b2c825a2
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsic-volatile.rs
@@ -0,0 +1,44 @@
+// run-pass
+
+#![feature(core_intrinsics)]
+
+use std::intrinsics::*;
+
+pub fn main() {
+ unsafe {
+ let mut x: Box<u8> = Box::new(0);
+ let mut y: Box<u8> = Box::new(0);
+
+ // test volatile load
+ assert_eq!(volatile_load(&*x), 0);
+ *x = 1;
+ assert_eq!(volatile_load(&*x), 1);
+
+ // test volatile store
+ volatile_store(&mut *x, 2);
+ assert_eq!(*x, 2);
+
+ // test volatile copy memory
+ volatile_copy_memory(&mut *y, &*x, 1);
+ assert_eq!(*y, 2);
+
+ // test volatile copy non-overlapping memory
+ *x = 3;
+ volatile_copy_nonoverlapping_memory(&mut *y, &*x, 1);
+ assert_eq!(*y, 3);
+
+ // test volatile set memory
+ volatile_set_memory(&mut *x, 4, 1);
+ assert_eq!(*x, 4);
+
+ // test unaligned volatile load
+ let arr: [u8; 3] = [1, 2, 3];
+ let ptr = arr[1..].as_ptr() as *const u16;
+ assert_eq!(unaligned_volatile_load(ptr), u16::from_ne_bytes([arr[1], arr[2]]));
+
+ // test unaligned volatile store
+ let ptr = arr[1..].as_ptr() as *mut u16;
+ unaligned_volatile_store(ptr, 0);
+ assert_eq!(arr, [1, 0, 0]);
+ }
+}
diff --git a/tests/ui/intrinsics/intrinsics-integer.rs b/tests/ui/intrinsics/intrinsics-integer.rs
new file mode 100644
index 000000000..88bf42b68
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsics-integer.rs
@@ -0,0 +1,177 @@
+// 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;
+ }
+}
+
+pub fn main() {
+ use rusti::*;
+
+ assert_eq!(ctpop(0u8), 0); assert_eq!(ctpop(0i8), 0);
+ assert_eq!(ctpop(0u16), 0); assert_eq!(ctpop(0i16), 0);
+ assert_eq!(ctpop(0u32), 0); assert_eq!(ctpop(0i32), 0);
+ assert_eq!(ctpop(0u64), 0); assert_eq!(ctpop(0i64), 0);
+ assert_eq!(ctpop(0u128), 0); assert_eq!(ctpop(0i128), 0);
+
+ assert_eq!(ctpop(1u8), 1); assert_eq!(ctpop(1i8), 1);
+ assert_eq!(ctpop(1u16), 1); assert_eq!(ctpop(1i16), 1);
+ assert_eq!(ctpop(1u32), 1); assert_eq!(ctpop(1i32), 1);
+ assert_eq!(ctpop(1u64), 1); assert_eq!(ctpop(1i64), 1);
+ assert_eq!(ctpop(1u128), 1); assert_eq!(ctpop(1i128), 1);
+
+ assert_eq!(ctpop(10u8), 2); assert_eq!(ctpop(10i8), 2);
+ assert_eq!(ctpop(10u16), 2); assert_eq!(ctpop(10i16), 2);
+ assert_eq!(ctpop(10u32), 2); assert_eq!(ctpop(10i32), 2);
+ assert_eq!(ctpop(10u64), 2); assert_eq!(ctpop(10i64), 2);
+ assert_eq!(ctpop(10u128), 2); assert_eq!(ctpop(10i128), 2);
+
+ assert_eq!(ctpop(100u8), 3); assert_eq!(ctpop(100i8), 3);
+ assert_eq!(ctpop(100u16), 3); assert_eq!(ctpop(100i16), 3);
+ assert_eq!(ctpop(100u32), 3); assert_eq!(ctpop(100i32), 3);
+ assert_eq!(ctpop(100u64), 3); assert_eq!(ctpop(100i64), 3);
+ assert_eq!(ctpop(100u128), 3); assert_eq!(ctpop(100i128), 3);
+
+ assert_eq!(ctpop(-1i8 as u8), 8); assert_eq!(ctpop(-1i8), 8);
+ assert_eq!(ctpop(-1i16 as u16), 16); assert_eq!(ctpop(-1i16), 16);
+ assert_eq!(ctpop(-1i32 as u32), 32); assert_eq!(ctpop(-1i32), 32);
+ assert_eq!(ctpop(-1i64 as u64), 64); assert_eq!(ctpop(-1i64), 64);
+ assert_eq!(ctpop(-1i128 as u128), 128); assert_eq!(ctpop(-1i128), 128);
+
+ assert_eq!(ctlz(0u8), 8); assert_eq!(ctlz(0i8), 8);
+ assert_eq!(ctlz(0u16), 16); assert_eq!(ctlz(0i16), 16);
+ assert_eq!(ctlz(0u32), 32); assert_eq!(ctlz(0i32), 32);
+ assert_eq!(ctlz(0u64), 64); assert_eq!(ctlz(0i64), 64);
+ assert_eq!(ctlz(0u128), 128); assert_eq!(ctlz(0i128), 128);
+
+ assert_eq!(ctlz(1u8), 7); assert_eq!(ctlz(1i8), 7);
+ assert_eq!(ctlz(1u16), 15); assert_eq!(ctlz(1i16), 15);
+ assert_eq!(ctlz(1u32), 31); assert_eq!(ctlz(1i32), 31);
+ assert_eq!(ctlz(1u64), 63); assert_eq!(ctlz(1i64), 63);
+ assert_eq!(ctlz(1u128), 127); assert_eq!(ctlz(1i128), 127);
+
+ assert_eq!(ctlz(10u8), 4); assert_eq!(ctlz(10i8), 4);
+ assert_eq!(ctlz(10u16), 12); assert_eq!(ctlz(10i16), 12);
+ assert_eq!(ctlz(10u32), 28); assert_eq!(ctlz(10i32), 28);
+ assert_eq!(ctlz(10u64), 60); assert_eq!(ctlz(10i64), 60);
+ assert_eq!(ctlz(10u128), 124); assert_eq!(ctlz(10i128), 124);
+
+ assert_eq!(ctlz(100u8), 1); assert_eq!(ctlz(100i8), 1);
+ assert_eq!(ctlz(100u16), 9); assert_eq!(ctlz(100i16), 9);
+ assert_eq!(ctlz(100u32), 25); assert_eq!(ctlz(100i32), 25);
+ assert_eq!(ctlz(100u64), 57); assert_eq!(ctlz(100i64), 57);
+ assert_eq!(ctlz(100u128), 121); assert_eq!(ctlz(100i128), 121);
+
+ unsafe {
+ assert_eq!(ctlz_nonzero(1u8), 7); assert_eq!(ctlz_nonzero(1i8), 7);
+ assert_eq!(ctlz_nonzero(1u16), 15); assert_eq!(ctlz_nonzero(1i16), 15);
+ assert_eq!(ctlz_nonzero(1u32), 31); assert_eq!(ctlz_nonzero(1i32), 31);
+ assert_eq!(ctlz_nonzero(1u64), 63); assert_eq!(ctlz_nonzero(1i64), 63);
+ assert_eq!(ctlz_nonzero(1u128), 127); assert_eq!(ctlz_nonzero(1i128), 127);
+
+ assert_eq!(ctlz_nonzero(10u8), 4); assert_eq!(ctlz_nonzero(10i8), 4);
+ assert_eq!(ctlz_nonzero(10u16), 12); assert_eq!(ctlz_nonzero(10i16), 12);
+ assert_eq!(ctlz_nonzero(10u32), 28); assert_eq!(ctlz_nonzero(10i32), 28);
+ assert_eq!(ctlz_nonzero(10u64), 60); assert_eq!(ctlz_nonzero(10i64), 60);
+ assert_eq!(ctlz_nonzero(10u128), 124); assert_eq!(ctlz_nonzero(10i128), 124);
+
+ assert_eq!(ctlz_nonzero(100u8), 1); assert_eq!(ctlz_nonzero(100i8), 1);
+ assert_eq!(ctlz_nonzero(100u16), 9); assert_eq!(ctlz_nonzero(100i16), 9);
+ assert_eq!(ctlz_nonzero(100u32), 25); assert_eq!(ctlz_nonzero(100i32), 25);
+ assert_eq!(ctlz_nonzero(100u64), 57); assert_eq!(ctlz_nonzero(100i64), 57);
+ assert_eq!(ctlz_nonzero(100u128), 121); assert_eq!(ctlz_nonzero(100i128), 121);
+ }
+
+ assert_eq!(cttz(-1i8 as u8), 0); assert_eq!(cttz(-1i8), 0);
+ assert_eq!(cttz(-1i16 as u16), 0); assert_eq!(cttz(-1i16), 0);
+ assert_eq!(cttz(-1i32 as u32), 0); assert_eq!(cttz(-1i32), 0);
+ assert_eq!(cttz(-1i64 as u64), 0); assert_eq!(cttz(-1i64), 0);
+ assert_eq!(cttz(-1i128 as u128), 0); assert_eq!(cttz(-1i128), 0);
+
+ assert_eq!(cttz(0u8), 8); assert_eq!(cttz(0i8), 8);
+ assert_eq!(cttz(0u16), 16); assert_eq!(cttz(0i16), 16);
+ assert_eq!(cttz(0u32), 32); assert_eq!(cttz(0i32), 32);
+ assert_eq!(cttz(0u64), 64); assert_eq!(cttz(0i64), 64);
+ assert_eq!(cttz(0u128), 128); assert_eq!(cttz(0i128), 128);
+
+ assert_eq!(cttz(1u8), 0); assert_eq!(cttz(1i8), 0);
+ assert_eq!(cttz(1u16), 0); assert_eq!(cttz(1i16), 0);
+ assert_eq!(cttz(1u32), 0); assert_eq!(cttz(1i32), 0);
+ assert_eq!(cttz(1u64), 0); assert_eq!(cttz(1i64), 0);
+ assert_eq!(cttz(1u128), 0); assert_eq!(cttz(1i128), 0);
+
+ assert_eq!(cttz(10u8), 1); assert_eq!(cttz(10i8), 1);
+ assert_eq!(cttz(10u16), 1); assert_eq!(cttz(10i16), 1);
+ assert_eq!(cttz(10u32), 1); assert_eq!(cttz(10i32), 1);
+ assert_eq!(cttz(10u64), 1); assert_eq!(cttz(10i64), 1);
+ assert_eq!(cttz(10u128), 1); assert_eq!(cttz(10i128), 1);
+
+ assert_eq!(cttz(100u8), 2); assert_eq!(cttz(100i8), 2);
+ assert_eq!(cttz(100u16), 2); assert_eq!(cttz(100i16), 2);
+ assert_eq!(cttz(100u32), 2); assert_eq!(cttz(100i32), 2);
+ assert_eq!(cttz(100u64), 2); assert_eq!(cttz(100i64), 2);
+ assert_eq!(cttz(100u128), 2); assert_eq!(cttz(100i128), 2);
+
+ unsafe {
+ assert_eq!(cttz_nonzero(-1i8 as u8), 0); assert_eq!(cttz_nonzero(-1i8), 0);
+ assert_eq!(cttz_nonzero(-1i16 as u16), 0); assert_eq!(cttz_nonzero(-1i16), 0);
+ assert_eq!(cttz_nonzero(-1i32 as u32), 0); assert_eq!(cttz_nonzero(-1i32), 0);
+ assert_eq!(cttz_nonzero(-1i64 as u64), 0); assert_eq!(cttz_nonzero(-1i64), 0);
+ assert_eq!(cttz_nonzero(-1i128 as u128), 0); assert_eq!(cttz_nonzero(-1i128), 0);
+
+ assert_eq!(cttz_nonzero(1u8), 0); assert_eq!(cttz_nonzero(1i8), 0);
+ assert_eq!(cttz_nonzero(1u16), 0); assert_eq!(cttz_nonzero(1i16), 0);
+ assert_eq!(cttz_nonzero(1u32), 0); assert_eq!(cttz_nonzero(1i32), 0);
+ assert_eq!(cttz_nonzero(1u64), 0); assert_eq!(cttz_nonzero(1i64), 0);
+ assert_eq!(cttz_nonzero(1u128), 0); assert_eq!(cttz_nonzero(1i128), 0);
+
+ assert_eq!(cttz_nonzero(10u8), 1); assert_eq!(cttz_nonzero(10i8), 1);
+ assert_eq!(cttz_nonzero(10u16), 1); assert_eq!(cttz_nonzero(10i16), 1);
+ assert_eq!(cttz_nonzero(10u32), 1); assert_eq!(cttz_nonzero(10i32), 1);
+ assert_eq!(cttz_nonzero(10u64), 1); assert_eq!(cttz_nonzero(10i64), 1);
+ assert_eq!(cttz_nonzero(10u128), 1); assert_eq!(cttz_nonzero(10i128), 1);
+
+ assert_eq!(cttz_nonzero(100u8), 2); assert_eq!(cttz_nonzero(100i8), 2);
+ assert_eq!(cttz_nonzero(100u16), 2); assert_eq!(cttz_nonzero(100i16), 2);
+ assert_eq!(cttz_nonzero(100u32), 2); assert_eq!(cttz_nonzero(100i32), 2);
+ assert_eq!(cttz_nonzero(100u64), 2); assert_eq!(cttz_nonzero(100i64), 2);
+ assert_eq!(cttz_nonzero(100u128), 2); assert_eq!(cttz_nonzero(100i128), 2);
+ }
+
+ assert_eq!(bswap(0x0Au8), 0x0A); // no-op
+ assert_eq!(bswap(0x0Ai8), 0x0A); // no-op
+ assert_eq!(bswap(0x0A0Bu16), 0x0B0A);
+ assert_eq!(bswap(0x0A0Bi16), 0x0B0A);
+ assert_eq!(bswap(0x0ABBCC0Du32), 0x0DCCBB0A);
+ assert_eq!(bswap(0x0ABBCC0Di32), 0x0DCCBB0A);
+ assert_eq!(bswap(0x0122334455667708u64), 0x0877665544332201);
+ assert_eq!(bswap(0x0122334455667708i64), 0x0877665544332201);
+ assert_eq!(bswap(0x0122334455667708u128), 0x08776655443322010000000000000000);
+ assert_eq!(bswap(0x0122334455667708i128), 0x08776655443322010000000000000000);
+
+ assert_eq!(bitreverse(0x0Au8), 0x50);
+ assert_eq!(bitreverse(0x0Ai8), 0x50);
+ assert_eq!(bitreverse(0x0A0Cu16), 0x3050);
+ assert_eq!(bitreverse(0x0A0Ci16), 0x3050);
+ assert_eq!(bitreverse(0x0ABBCC0Eu32), 0x7033DD50);
+ assert_eq!(bitreverse(0x0ABBCC0Ei32), 0x7033DD50);
+ assert_eq!(bitreverse(0x0122334455667708u64), 0x10EE66AA22CC4480);
+ assert_eq!(bitreverse(0x0122334455667708i64), 0x10EE66AA22CC4480);
+ assert_eq!(bitreverse(0x0122334455667708u128), 0x10EE66AA22CC44800000000000000000);
+ assert_eq!(bitreverse(0x0122334455667708i128), 0x10EE66AA22CC44800000000000000000);
+}
diff --git a/tests/ui/intrinsics/intrinsics-math.rs b/tests/ui/intrinsics/intrinsics-math.rs
new file mode 100644
index 000000000..aea9fde69
--- /dev/null
+++ b/tests/ui/intrinsics/intrinsics-math.rs
@@ -0,0 +1,60 @@
+// run-pass
+// ignore-emscripten fma not implemented in emscripten
+
+macro_rules! assert_approx_eq {
+ ($a:expr, $b:expr) => ({
+ let (a, b) = (&$a, &$b);
+ assert!((*a - *b).abs() < 1.0e-6,
+ "{} is not approximately equal to {}", *a, *b);
+ })
+}
+
+pub fn main() {
+ use std::f32;
+ use std::f64;
+
+ assert_approx_eq!(64f32.sqrt(), 8f32);
+ assert_approx_eq!(64f64.sqrt(), 8f64);
+
+ assert_approx_eq!(25f32.powi(-2), 0.0016f32);
+ assert_approx_eq!(23.2f64.powi(2), 538.24f64);
+
+ assert_approx_eq!(0f32.sin(), 0f32);
+ assert_approx_eq!((f64::consts::PI / 2f64).sin(), 1f64);
+
+ assert_approx_eq!(0f32.cos(), 1f32);
+ assert_approx_eq!((f64::consts::PI * 2f64).cos(), 1f64);
+
+ assert_approx_eq!(25f32.powf(-2f32), 0.0016f32);
+ assert_approx_eq!(400f64.powf(0.5f64), 20f64);
+
+ assert_approx_eq!((1f32.exp() - f32::consts::E).abs(), 0f32);
+ assert_approx_eq!(1f64.exp(), f64::consts::E);
+
+ assert_approx_eq!(10f32.exp2(), 1024f32);
+ assert_approx_eq!(50f64.exp2(), 1125899906842624f64);
+
+ assert_approx_eq!((f32::consts::E.ln() - 1f32).abs(), 0f32);
+ assert_approx_eq!(1f64.ln(), 0f64);
+
+ assert_approx_eq!(10f32.log10(), 1f32);
+ assert_approx_eq!(f64::consts::E.log10(), f64::consts::LOG10_E);
+
+ assert_approx_eq!(8f32.log2(), 3f32);
+ assert_approx_eq!(f64::consts::E.log2(), f64::consts::LOG2_E);
+
+ assert_approx_eq!(1.0f32.mul_add(2.0f32, 5.0f32), 7.0f32);
+ assert_approx_eq!(0.0f64.mul_add(-2.0f64, f64::consts::E), f64::consts::E);
+
+ assert_approx_eq!((-1.0f32).abs(), 1.0f32);
+ assert_approx_eq!(34.2f64.abs(), 34.2f64);
+
+ assert_approx_eq!(3.8f32.floor(), 3.0f32);
+ assert_approx_eq!((-1.1f64).floor(), -2.0f64);
+
+ assert_approx_eq!((-2.3f32).ceil(), -2.0f32);
+ assert_approx_eq!(3.8f64.ceil(), 4.0f64);
+
+ assert_approx_eq!(0.1f32.trunc(), 0.0f32);
+ assert_approx_eq!((-0.1f64).trunc(), 0.0f64);
+}
diff --git a/tests/ui/intrinsics/issue-28575.mir.stderr b/tests/ui/intrinsics/issue-28575.mir.stderr
new file mode 100644
index 000000000..c42498390
--- /dev/null
+++ b/tests/ui/intrinsics/issue-28575.mir.stderr
@@ -0,0 +1,11 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/issue-28575.rs:11:5
+ |
+LL | FOO()
+ | ^^^ use of extern static
+ |
+ = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/intrinsics/issue-28575.rs b/tests/ui/intrinsics/issue-28575.rs
new file mode 100644
index 000000000..410f664f8
--- /dev/null
+++ b/tests/ui/intrinsics/issue-28575.rs
@@ -0,0 +1,12 @@
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+#![feature(intrinsics)]
+
+extern "C" {
+ pub static FOO: extern "rust-intrinsic" fn();
+}
+
+fn main() {
+ FOO() //~ ERROR: use of extern static is unsafe
+}
diff --git a/tests/ui/intrinsics/issue-28575.thir.stderr b/tests/ui/intrinsics/issue-28575.thir.stderr
new file mode 100644
index 000000000..c42498390
--- /dev/null
+++ b/tests/ui/intrinsics/issue-28575.thir.stderr
@@ -0,0 +1,11 @@
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+ --> $DIR/issue-28575.rs:11:5
+ |
+LL | FOO()
+ | ^^^ use of extern static
+ |
+ = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/intrinsics/issue-84297-reifying-copy.rs b/tests/ui/intrinsics/issue-84297-reifying-copy.rs
new file mode 100644
index 000000000..08ba9ce7e
--- /dev/null
+++ b/tests/ui/intrinsics/issue-84297-reifying-copy.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+fn main() {
+ let _unused = if true {
+ core::ptr::copy::<i32>
+ } else {
+ core::ptr::copy_nonoverlapping::<i32>
+ };
+}
diff --git a/tests/ui/intrinsics/non-integer-atomic.rs b/tests/ui/intrinsics/non-integer-atomic.rs
new file mode 100644
index 000000000..85ea81ba6
--- /dev/null
+++ b/tests/ui/intrinsics/non-integer-atomic.rs
@@ -0,0 +1,92 @@
+// build-fail
+
+#![feature(core_intrinsics)]
+#![allow(warnings)]
+#![crate_type = "rlib"]
+
+use std::intrinsics;
+
+#[derive(Copy, Clone)]
+pub struct Foo(i64);
+pub type Bar = &'static Fn();
+pub type Quux = [u8; 100];
+
+pub unsafe fn test_bool_load(p: &mut bool, v: bool) {
+ intrinsics::atomic_load_seqcst(p);
+ //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `bool`
+}
+
+pub unsafe fn test_bool_store(p: &mut bool, v: bool) {
+ intrinsics::atomic_store_seqcst(p, v);
+ //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool`
+}
+
+pub unsafe fn test_bool_xchg(p: &mut bool, v: bool) {
+ intrinsics::atomic_xchg_seqcst(p, v);
+ //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool`
+}
+
+pub unsafe fn test_bool_cxchg(p: &mut bool, v: bool) {
+ intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+ //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool`
+}
+
+pub unsafe fn test_Foo_load(p: &mut Foo, v: Foo) {
+ intrinsics::atomic_load_seqcst(p);
+ //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `Foo`
+}
+
+pub unsafe fn test_Foo_store(p: &mut Foo, v: Foo) {
+ intrinsics::atomic_store_seqcst(p, v);
+ //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo`
+}
+
+pub unsafe fn test_Foo_xchg(p: &mut Foo, v: Foo) {
+ intrinsics::atomic_xchg_seqcst(p, v);
+ //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo`
+}
+
+pub unsafe fn test_Foo_cxchg(p: &mut Foo, v: Foo) {
+ intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+ //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo`
+}
+
+pub unsafe fn test_Bar_load(p: &mut Bar, v: Bar) {
+ intrinsics::atomic_load_seqcst(p);
+ //~^ ERROR expected basic integer type, found `&dyn Fn()`
+}
+
+pub unsafe fn test_Bar_store(p: &mut Bar, v: Bar) {
+ intrinsics::atomic_store_seqcst(p, v);
+ //~^ ERROR expected basic integer type, found `&dyn Fn()`
+}
+
+pub unsafe fn test_Bar_xchg(p: &mut Bar, v: Bar) {
+ intrinsics::atomic_xchg_seqcst(p, v);
+ //~^ ERROR expected basic integer type, found `&dyn Fn()`
+}
+
+pub unsafe fn test_Bar_cxchg(p: &mut Bar, v: Bar) {
+ intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+ //~^ ERROR expected basic integer type, found `&dyn Fn()`
+}
+
+pub unsafe fn test_Quux_load(p: &mut Quux, v: Quux) {
+ intrinsics::atomic_load_seqcst(p);
+ //~^ ERROR `atomic_load_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+}
+
+pub unsafe fn test_Quux_store(p: &mut Quux, v: Quux) {
+ intrinsics::atomic_store_seqcst(p, v);
+ //~^ ERROR `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+}
+
+pub unsafe fn test_Quux_xchg(p: &mut Quux, v: Quux) {
+ intrinsics::atomic_xchg_seqcst(p, v);
+ //~^ ERROR `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+}
+
+pub unsafe fn test_Quux_cxchg(p: &mut Quux, v: Quux) {
+ intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+ //~^ ERROR `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+}
diff --git a/tests/ui/intrinsics/non-integer-atomic.stderr b/tests/ui/intrinsics/non-integer-atomic.stderr
new file mode 100644
index 000000000..32791a8e8
--- /dev/null
+++ b/tests/ui/intrinsics/non-integer-atomic.stderr
@@ -0,0 +1,99 @@
+error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `bool`
+ --> $DIR/non-integer-atomic.rs:15:5
+ |
+LL | intrinsics::atomic_load_seqcst(p);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `bool`
+ --> $DIR/non-integer-atomic.rs:20:5
+ |
+LL | intrinsics::atomic_store_seqcst(p, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `bool`
+ --> $DIR/non-integer-atomic.rs:25:5
+ |
+LL | intrinsics::atomic_xchg_seqcst(p, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `bool`
+ --> $DIR/non-integer-atomic.rs:30:5
+ |
+LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `Foo`
+ --> $DIR/non-integer-atomic.rs:35:5
+ |
+LL | intrinsics::atomic_load_seqcst(p);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `Foo`
+ --> $DIR/non-integer-atomic.rs:40:5
+ |
+LL | intrinsics::atomic_store_seqcst(p, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `Foo`
+ --> $DIR/non-integer-atomic.rs:45:5
+ |
+LL | intrinsics::atomic_xchg_seqcst(p, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `Foo`
+ --> $DIR/non-integer-atomic.rs:50:5
+ |
+LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
+ --> $DIR/non-integer-atomic.rs:55:5
+ |
+LL | intrinsics::atomic_load_seqcst(p);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
+ --> $DIR/non-integer-atomic.rs:60:5
+ |
+LL | intrinsics::atomic_store_seqcst(p, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
+ --> $DIR/non-integer-atomic.rs:65:5
+ |
+LL | intrinsics::atomic_xchg_seqcst(p, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `&dyn Fn()`
+ --> $DIR/non-integer-atomic.rs:70:5
+ |
+LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_load_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+ --> $DIR/non-integer-atomic.rs:75:5
+ |
+LL | intrinsics::atomic_load_seqcst(p);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_store_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+ --> $DIR/non-integer-atomic.rs:80:5
+ |
+LL | intrinsics::atomic_store_seqcst(p, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_xchg_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+ --> $DIR/non-integer-atomic.rs:85:5
+ |
+LL | intrinsics::atomic_xchg_seqcst(p, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `atomic_cxchg_seqcst_seqcst` intrinsic: expected basic integer type, found `[u8; 100]`
+ --> $DIR/non-integer-atomic.rs:90:5
+ |
+LL | intrinsics::atomic_cxchg_seqcst_seqcst(p, v, v);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 16 previous errors
+
+For more information about this error, try `rustc --explain E0511`.
diff --git a/tests/ui/intrinsics/panic-uninitialized-zeroed.rs b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs
new file mode 100644
index 000000000..1a0104b85
--- /dev/null
+++ b/tests/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -0,0 +1,397 @@
+// run-pass
+// revisions: default strict
+// [strict]compile-flags: -Zstrict-init-checks
+// ignore-tidy-linelength
+// ignore-emscripten spawning processes is not supported
+// ignore-sgx no processes
+
+// This test checks panic emitted from `mem::{uninitialized,zeroed}`.
+
+#![feature(never_type)]
+#![allow(deprecated, invalid_value)]
+
+use std::{
+ mem::{self, MaybeUninit, ManuallyDrop},
+ ptr::NonNull,
+ num,
+};
+
+#[allow(dead_code)]
+struct Foo {
+ x: u8,
+ y: !,
+}
+
+enum Bar {}
+
+#[allow(dead_code)]
+enum OneVariant { Variant(i32) }
+
+#[allow(dead_code, non_camel_case_types)]
+enum OneVariant_NonZero {
+ Variant(i32, i32, num::NonZeroI32),
+ DeadVariant(Bar),
+}
+
+#[allow(dead_code, non_camel_case_types)]
+enum OneVariant_Ref {
+ Variant(&'static i32),
+ DeadVariant(Bar),
+}
+
+// An `Aggregate` abi enum where 0 is not a valid discriminant.
+#[allow(dead_code)]
+#[repr(i32)]
+enum NoNullVariant {
+ Variant1(i32, i32) = 1,
+ Variant2(i32, i32) = 2,
+}
+
+// An enum with ScalarPair layout
+#[allow(dead_code)]
+enum LR {
+ Left(i64),
+ Right(i64),
+}
+#[allow(dead_code, non_camel_case_types)]
+enum LR_NonZero {
+ Left(num::NonZeroI64),
+ Right(num::NonZeroI64),
+}
+
+struct ZeroSized;
+
+#[allow(dead_code)]
+#[repr(i32)]
+enum ZeroIsValid {
+ Zero(u8) = 0,
+ One(NonNull<()>) = 1,
+}
+
+#[track_caller]
+fn test_panic_msg<T, F: (FnOnce() -> T) + 'static>(op: F, msg: &str) {
+ use std::{panic, env, process};
+
+ // The tricky part is that we can't just run `op`, as that would *abort* the process.
+ // So instead, we reinvoke this process with the caller location as argument.
+ // For the purpose of this test, the line number is unique enough.
+ // If we are running in such a re-invocation, we skip all the tests *except* for the one with that type name.
+ let our_loc = panic::Location::caller().line().to_string();
+ let mut args = env::args();
+ let this = args.next().unwrap();
+ if let Some(loc) = args.next() {
+ if loc == our_loc {
+ op();
+ panic!("we did not abort");
+ } else {
+ // Nothing, we are running another test.
+ }
+ } else {
+ // Invoke new process for actual test, and check result.
+ let mut cmd = process::Command::new(this);
+ cmd.arg(our_loc);
+ let res = cmd.output().unwrap();
+ assert!(!res.status.success(), "test did not fail");
+ let stderr = String::from_utf8_lossy(&res.stderr);
+ assert!(stderr.contains(msg), "test did not contain expected output: looking for {:?}, output:\n{}", msg, stderr);
+ }
+}
+
+#[track_caller]
+fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + 'static, msg: &str) {
+ if !cfg!(strict) {
+ // Just run it.
+ op();
+ } else {
+ test_panic_msg(op, msg);
+ }
+}
+
+fn main() {
+ unsafe {
+ // Uninhabited types
+ test_panic_msg(
+ || mem::uninitialized::<!>(),
+ "attempted to instantiate uninhabited type `!`"
+ );
+ test_panic_msg(
+ || mem::zeroed::<!>(),
+ "attempted to instantiate uninhabited type `!`"
+ );
+ test_panic_msg(
+ || MaybeUninit::<!>::uninit().assume_init(),
+ "attempted to instantiate uninhabited type `!`"
+ );
+
+ test_panic_msg(
+ || mem::uninitialized::<Foo>(),
+ "attempted to instantiate uninhabited type `Foo`"
+ );
+ test_panic_msg(
+ || mem::zeroed::<Foo>(),
+ "attempted to instantiate uninhabited type `Foo`"
+ );
+ test_panic_msg(
+ || MaybeUninit::<Foo>::uninit().assume_init(),
+ "attempted to instantiate uninhabited type `Foo`"
+ );
+
+ test_panic_msg(
+ || mem::uninitialized::<Bar>(),
+ "attempted to instantiate uninhabited type `Bar`"
+ );
+ test_panic_msg(
+ || mem::zeroed::<Bar>(),
+ "attempted to instantiate uninhabited type `Bar`"
+ );
+ test_panic_msg(
+ || MaybeUninit::<Bar>::uninit().assume_init(),
+ "attempted to instantiate uninhabited type `Bar`"
+ );
+
+ test_panic_msg(
+ || mem::uninitialized::<[Foo; 2]>(),
+ "attempted to instantiate uninhabited type `[Foo; 2]`"
+ );
+ test_panic_msg(
+ || mem::zeroed::<[Foo; 2]>(),
+ "attempted to instantiate uninhabited type `[Foo; 2]`"
+ );
+ test_panic_msg(
+ || MaybeUninit::<[Foo; 2]>::uninit().assume_init(),
+ "attempted to instantiate uninhabited type `[Foo; 2]`"
+ );
+
+ test_panic_msg(
+ || mem::uninitialized::<[Bar; 2]>(),
+ "attempted to instantiate uninhabited type `[Bar; 2]`"
+ );
+ test_panic_msg(
+ || mem::zeroed::<[Bar; 2]>(),
+ "attempted to instantiate uninhabited type `[Bar; 2]`"
+ );
+ test_panic_msg(
+ || MaybeUninit::<[Bar; 2]>::uninit().assume_init(),
+ "attempted to instantiate uninhabited type `[Bar; 2]`"
+ );
+
+ // Types that don't allow either.
+ test_panic_msg(
+ || mem::zeroed::<&i32>(),
+ "attempted to zero-initialize type `&i32`, which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<&i32>(),
+ "attempted to leave type `&i32` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<Box<[i32; 0]>>(),
+ "attempted to zero-initialize type `alloc::boxed::Box<[i32; 0]>`, which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<Box<[i32; 0]>>(),
+ "attempted to leave type `alloc::boxed::Box<[i32; 0]>` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<Box<u8>>(),
+ "attempted to zero-initialize type `alloc::boxed::Box<u8>`, which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<Box<u8>>(),
+ "attempted to leave type `alloc::boxed::Box<u8>` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<&[i32]>(),
+ "attempted to zero-initialize type `&[i32]`, which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<&[i32]>(),
+ "attempted to leave type `&[i32]` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<&(u8, [u8])>(),
+ "attempted to zero-initialize type `&(u8, [u8])`, which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<&(u8, [u8])>(),
+ "attempted to leave type `&(u8, [u8])` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<&dyn Send>(),
+ "attempted to zero-initialize type `&dyn core::marker::Send`, which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<&dyn Send>(),
+ "attempted to leave type `&dyn core::marker::Send` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<*const dyn Send>(),
+ "attempted to zero-initialize type `*const dyn core::marker::Send`, which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<*const dyn Send>(),
+ "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::uninitialized::<NoNullVariant>(),
+ "attempted to leave type `NoNullVariant` uninitialized, \
+ which is invalid"
+ );
+ test_panic_msg(
+ || mem::zeroed::<NoNullVariant>(),
+ "attempted to zero-initialize type `NoNullVariant`, \
+ which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<OneVariant_Ref>(),
+ "attempted to zero-initialize type `OneVariant_Ref`, \
+ which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<OneVariant_Ref>(),
+ "attempted to leave type `OneVariant_Ref` uninitialized, which is invalid"
+ );
+
+ // Types where both are invalid, but we allow uninit since the 0x01-filling is not LLVM UB.
+ test_panic_msg(
+ || mem::zeroed::<fn()>(),
+ "attempted to zero-initialize type `fn()`, which is invalid"
+ );
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<fn()>(),
+ "attempted to leave type `fn()` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<&()>(),
+ "attempted to zero-initialize type `&()`, which is invalid"
+ );
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<&()>(),
+ "attempted to leave type `&()` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<&[u8]>(),
+ "attempted to zero-initialize type `&[u8]`, which is invalid"
+ );
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<&[u8]>(),
+ "attempted to leave type `&[u8]` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<&str>(),
+ "attempted to zero-initialize type `&str`, which is invalid"
+ );
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<&str>(),
+ "attempted to leave type `&str` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<(NonNull<u32>, u32, u32)>(),
+ "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
+ which is invalid"
+ );
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<(NonNull<u32>, u32, u32)>(),
+ "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, which is invalid"
+ );
+
+ test_panic_msg(
+ || mem::zeroed::<OneVariant_NonZero>(),
+ "attempted to zero-initialize type `OneVariant_NonZero`, \
+ which is invalid"
+ );
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<OneVariant_NonZero>(),
+ "attempted to leave type `OneVariant_NonZero` uninitialized, which is invalid"
+ );
+
+ // Types where both are invalid but we allow the zeroed form since it is not LLVM UB.
+ test_panic_msg_only_if_strict(
+ || mem::zeroed::<LR_NonZero>(),
+ "attempted to zero-initialize type `LR_NonZero`, which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<LR_NonZero>(),
+ "attempted to leave type `LR_NonZero` uninitialized, which is invalid"
+ );
+
+ test_panic_msg_only_if_strict(
+ || mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
+ "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \
+ which is invalid"
+ );
+ test_panic_msg(
+ || mem::uninitialized::<ManuallyDrop<LR_NonZero>>(),
+ "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>` uninitialized, \
+ which is invalid"
+ );
+
+ // Some strict-only things
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<i32>(),
+ "attempted to leave type `i32` uninitialized, which is invalid"
+ );
+
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<*const ()>(),
+ "attempted to leave type `*const ()` uninitialized, which is invalid"
+ );
+
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<[i32; 1]>(),
+ "attempted to leave type `[i32; 1]` uninitialized, which is invalid"
+ );
+
+ test_panic_msg_only_if_strict(
+ || mem::zeroed::<[NonNull<()>; 1]>(),
+ "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid"
+ );
+
+ // Types that can be zero, but not uninit (though some are mitigated).
+ let _val = mem::zeroed::<LR>();
+ test_panic_msg(
+ || mem::uninitialized::<LR>(),
+ "attempted to leave type `LR` uninitialized, which is invalid"
+ );
+
+ let _val = mem::zeroed::<ManuallyDrop<LR>>();
+ test_panic_msg(
+ || mem::uninitialized::<ManuallyDrop<LR>>(),
+ "attempted to leave type `core::mem::manually_drop::ManuallyDrop<LR>` uninitialized, which is invalid"
+ );
+
+ let _val = mem::zeroed::<bool>();
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<bool>(),
+ "attempted to leave type `bool` uninitialized, which is invalid"
+ );
+
+ let _val = mem::zeroed::<OneVariant>();
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<OneVariant>(),
+ "attempted to leave type `OneVariant` uninitialized, which is invalid"
+ );
+
+ // Some things that are actually allowed.
+ let _val = mem::zeroed::<Option<&'static i32>>();
+ let _val = mem::zeroed::<MaybeUninit<NonNull<u32>>>();
+ let _val = mem::zeroed::<[!; 0]>();
+ let _val = mem::zeroed::<ZeroIsValid>();
+ let _val = mem::uninitialized::<MaybeUninit<bool>>();
+ let _val = mem::uninitialized::<[!; 0]>();
+ let _val = mem::uninitialized::<()>();
+ let _val = mem::uninitialized::<ZeroSized>();
+ }
+}
diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.rs b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
new file mode 100644
index 000000000..50e12eaeb
--- /dev/null
+++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.rs
@@ -0,0 +1,11 @@
+#![feature(intrinsics)]
+#![feature(rustc_attrs)]
+
+extern "rust-intrinsic" {
+ fn size_of<T>() -> usize; //~ ERROR intrinsic safety mismatch
+
+ #[rustc_safe_intrinsic]
+ fn assume(b: bool); //~ ERROR intrinsic safety mismatch
+}
+
+fn main() {}
diff --git a/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
new file mode 100644
index 000000000..0c2f3be49
--- /dev/null
+++ b/tests/ui/intrinsics/safe-intrinsic-mismatch.stderr
@@ -0,0 +1,14 @@
+error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `size_of`
+ --> $DIR/safe-intrinsic-mismatch.rs:5:5
+ |
+LL | fn size_of<T>() -> usize;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: intrinsic safety mismatch between list of intrinsics within the compiler and core library intrinsics for intrinsic `assume`
+ --> $DIR/safe-intrinsic-mismatch.rs:8:5
+ |
+LL | fn assume(b: bool);
+ | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/intrinsics/unchecked_math_unsafe.mir.stderr b/tests/ui/intrinsics/unchecked_math_unsafe.mir.stderr
new file mode 100644
index 000000000..26b2f9f27
--- /dev/null
+++ b/tests/ui/intrinsics/unchecked_math_unsafe.mir.stderr
@@ -0,0 +1,27 @@
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+ --> $DIR/unchecked_math_unsafe.rs:8:15
+ |
+LL | let add = std::intrinsics::unchecked_add(x, y);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+ --> $DIR/unchecked_math_unsafe.rs:9:15
+ |
+LL | let sub = std::intrinsics::unchecked_sub(x, y);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
+ --> $DIR/unchecked_math_unsafe.rs:10:15
+ |
+LL | let mul = std::intrinsics::unchecked_mul(x, y);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/intrinsics/unchecked_math_unsafe.rs b/tests/ui/intrinsics/unchecked_math_unsafe.rs
new file mode 100644
index 000000000..98d3a11ad
--- /dev/null
+++ b/tests/ui/intrinsics/unchecked_math_unsafe.rs
@@ -0,0 +1,11 @@
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
+#![feature(core_intrinsics)]
+
+fn main() {
+ let (x, y) = (1u32, 2u32);
+ let add = std::intrinsics::unchecked_add(x, y); //~ ERROR call to unsafe function
+ let sub = std::intrinsics::unchecked_sub(x, y); //~ ERROR call to unsafe function
+ let mul = std::intrinsics::unchecked_mul(x, y); //~ ERROR call to unsafe function
+}
diff --git a/tests/ui/intrinsics/unchecked_math_unsafe.thir.stderr b/tests/ui/intrinsics/unchecked_math_unsafe.thir.stderr
new file mode 100644
index 000000000..5c3728ccd
--- /dev/null
+++ b/tests/ui/intrinsics/unchecked_math_unsafe.thir.stderr
@@ -0,0 +1,27 @@
+error[E0133]: call to unsafe function `unchecked_add` is unsafe and requires unsafe function or block
+ --> $DIR/unchecked_math_unsafe.rs:8:15
+ |
+LL | let add = std::intrinsics::unchecked_add(x, y);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function `unchecked_sub` is unsafe and requires unsafe function or block
+ --> $DIR/unchecked_math_unsafe.rs:9:15
+ |
+LL | let sub = std::intrinsics::unchecked_sub(x, y);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function `unchecked_mul` is unsafe and requires unsafe function or block
+ --> $DIR/unchecked_math_unsafe.rs:10:15
+ |
+LL | let mul = std::intrinsics::unchecked_mul(x, y);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
+ |
+ = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/intrinsics/unchecked_math_unstable.rs b/tests/ui/intrinsics/unchecked_math_unstable.rs
new file mode 100644
index 000000000..8869063d1
--- /dev/null
+++ b/tests/ui/intrinsics/unchecked_math_unstable.rs
@@ -0,0 +1,8 @@
+fn main() {
+ let (x, y) = (1u32, 2u32);
+ unsafe {
+ let add = std::intrinsics::unchecked_add(x, y); //~ ERROR use of unstable library feature
+ let sub = std::intrinsics::unchecked_sub(x, y); //~ ERROR use of unstable library feature
+ let mul = std::intrinsics::unchecked_mul(x, y); //~ ERROR use of unstable library feature
+ }
+}
diff --git a/tests/ui/intrinsics/unchecked_math_unstable.stderr b/tests/ui/intrinsics/unchecked_math_unstable.stderr
new file mode 100644
index 000000000..a43aa16ae
--- /dev/null
+++ b/tests/ui/intrinsics/unchecked_math_unstable.stderr
@@ -0,0 +1,27 @@
+error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library
+ --> $DIR/unchecked_math_unstable.rs:4:19
+ |
+LL | let add = std::intrinsics::unchecked_add(x, y);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library
+ --> $DIR/unchecked_math_unstable.rs:5:19
+ |
+LL | let sub = std::intrinsics::unchecked_sub(x, y);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable
+
+error[E0658]: use of unstable library feature 'core_intrinsics': intrinsics are unlikely to ever be stabilized, instead they should be used through stabilized interfaces in the rest of the standard library
+ --> $DIR/unchecked_math_unstable.rs:6:19
+ |
+LL | let mul = std::intrinsics::unchecked_mul(x, y);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(core_intrinsics)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0658`.