summaryrefslogtreecommitdiffstats
path: root/src/test/ui/intrinsics
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace-std.rs7
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr2
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace.rs19
-rw-r--r--src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr2
-rw-r--r--src/test/ui/intrinsics/const-eval-select-bad.rs14
-rw-r--r--src/test/ui/intrinsics/const-eval-select-bad.stderr85
-rw-r--r--src/test/ui/intrinsics/intrinsic-alignment.rs1
-rw-r--r--src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.rs1
-rw-r--r--src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr2
-rw-r--r--src/test/ui/intrinsics/intrinsic-raw_eq-const.rs1
-rw-r--r--src/test/ui/intrinsics/intrinsics-integer.rs6
-rw-r--r--src/test/ui/intrinsics/panic-uninitialized-zeroed.rs253
-rw-r--r--src/test/ui/intrinsics/safe-intrinsic-mismatch.rs11
-rw-r--r--src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr14
14 files changed, 298 insertions, 120 deletions
diff --git a/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs b/src/test/ui/intrinsics/const-eval-select-backtrace-std.rs
new file mode 100644
index 000000000..1164a3a5b
--- /dev/null
+++ b/src/test/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/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr b/src/test/ui/intrinsics/const-eval-select-backtrace-std.run.stderr
new file mode 100644
index 000000000..463cd52c5
--- /dev/null
+++ b/src/test/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/src/test/ui/intrinsics/const-eval-select-backtrace.rs b/src/test/ui/intrinsics/const-eval-select-backtrace.rs
new file mode 100644
index 000000000..ef1c7c419
--- /dev/null
+++ b/src/test/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/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr b/src/test/ui/intrinsics/const-eval-select-backtrace.run.stderr
new file mode 100644
index 000000000..54e28db5e
--- /dev/null
+++ b/src/test/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/src/test/ui/intrinsics/const-eval-select-bad.rs b/src/test/ui/intrinsics/const-eval-select-bad.rs
index 52f4e594f..fa14efad7 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.rs
+++ b/src/test/ui/intrinsics/const-eval-select-bad.rs
@@ -5,10 +5,13 @@ use std::intrinsics::const_eval_select;
const fn not_fn_items() {
const_eval_select((), || {}, || {});
- //~^ ERROR the trait bound
+ //~^ ERROR this argument must be a function item
+ //~| ERROR this argument must be a function item
const_eval_select((), 42, 0xDEADBEEF);
- //~^ ERROR the trait bound
+ //~^ 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 {
@@ -27,7 +30,7 @@ fn baz(n: bool) -> i32 {
const fn return_ty_mismatch() {
const_eval_select((1,), foo, bar);
- //~^ ERROR type mismatch
+ //~^ ERROR expected `fn(i32) -> bool {bar}` to be a fn item that returns `i32`, but it returns `bool`
}
const fn args_ty_mismatch() {
@@ -35,4 +38,9 @@ const fn args_ty_mismatch() {
//~^ 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/src/test/ui/intrinsics/const-eval-select-bad.stderr b/src/test/ui/intrinsics/const-eval-select-bad.stderr
index 89dba12c8..3720528ad 100644
--- a/src/test/ui/intrinsics/const-eval-select-bad.stderr
+++ b/src/test/ui/intrinsics/const-eval-select-bad.stderr
@@ -1,42 +1,57 @@
-error[E0277]: the trait bound `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]: FnOnce<()>` is not satisfied
+error: this argument must be a function item
--> $DIR/const-eval-select-bad.rs:7:27
|
LL | const_eval_select((), || {}, || {});
- | ----------------- ^^^^^ expected an `FnOnce<()>` closure, found `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]`
- | |
- | required by a bound introduced by this call
+ | ^^^^^
|
- = help: the trait `~const FnOnce<()>` is not implemented for `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]`
-note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]`, but that implementation is not `const`
- --> $DIR/const-eval-select-bad.rs:7:27
+ = 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: wrap the `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:29]` in a closure with no arguments: `|| { /* code */ }`
-note: required by a bound in `const_eval_select`
- --> $SRC_DIR/core/src/intrinsics.rs:LL:COL
+ | ^^^^^
|
-LL | F: ~const FnOnce<ARG, Output = RET>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `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[E0277]: the trait bound `{integer}: FnOnce<()>` is not satisfied
- --> $DIR/const-eval-select-bad.rs:9:27
+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 `~const FnOnce<()>` is not implemented for `{integer}`
+ = 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
|
-LL | F: ~const FnOnce<ARG, Output = RET>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL | F: FnOnce<ARG, Output = RET>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+
+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:9:31
+ --> $DIR/const-eval-select-bad.rs:10:31
|
LL | const_eval_select((), 42, 0xDEADBEEF);
| ----------------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}`
@@ -48,23 +63,25 @@ LL | const_eval_select((), 42, 0xDEADBEEF);
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
-LL | G: FnOnce<ARG, Output = RET> + ~const Destruct,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL | G: FnOnce<ARG, Output = RET>,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
-error[E0271]: type mismatch resolving `<fn(i32) -> bool {bar} as FnOnce<(i32,)>>::Output == i32`
- --> $DIR/const-eval-select-bad.rs:29:5
+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`
+ | ----------------- ^^^ 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
|
-LL | G: FnOnce<ARG, Output = RET> + ~const Destruct,
- | ^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL | G: FnOnce<ARG, Output = RET>,
+ | ^^^^^^^^^^^^ required by this bound in `const_eval_select`
error[E0631]: type mismatch in function arguments
- --> $DIR/const-eval-select-bad.rs:34:32
+ --> $DIR/const-eval-select-bad.rs:37:32
|
LL | const fn foo(n: i32) -> i32 {
| --------------------------- found signature defined here
@@ -79,10 +96,18 @@ LL | const_eval_select((true,), foo, baz);
note: required by a bound in `const_eval_select`
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
-LL | F: ~const FnOnce<ARG, Output = RET>,
- | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+LL | F: FnOnce<ARG, Output = RET>;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
+
+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 5 previous errors
+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/src/test/ui/intrinsics/intrinsic-alignment.rs b/src/test/ui/intrinsics/intrinsic-alignment.rs
index 6007eba8c..c8b1ff1db 100644
--- a/src/test/ui/intrinsics/intrinsic-alignment.rs
+++ b/src/test/ui/intrinsics/intrinsic-alignment.rs
@@ -6,6 +6,7 @@
mod rusti {
extern "rust-intrinsic" {
pub fn pref_align_of<T>() -> usize;
+ #[rustc_safe_intrinsic]
pub fn min_align_of<T>() -> usize;
}
}
diff --git a/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.rs b/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.rs
index a205a8730..a93d777d2 100644
--- a/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.rs
+++ b/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.rs
@@ -1,6 +1,5 @@
#![feature(core_intrinsics)]
#![feature(const_intrinsic_raw_eq)]
-#![deny(const_err)]
const BAD_RAW_EQ_CALL: bool = unsafe {
std::intrinsics::raw_eq(&(1_u8, 2_u16), &(1_u8, 2_u16))
diff --git a/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr b/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr
index 9322654b2..56d5a4857 100644
--- a/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr
+++ b/src/test/ui/intrinsics/intrinsic-raw_eq-const-padding.stderr
@@ -1,5 +1,5 @@
error[E0080]: evaluation of constant value failed
- --> $DIR/intrinsic-raw_eq-const-padding.rs:6:5
+ --> $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
diff --git a/src/test/ui/intrinsics/intrinsic-raw_eq-const.rs b/src/test/ui/intrinsics/intrinsic-raw_eq-const.rs
index 8ea954673..32841f531 100644
--- a/src/test/ui/intrinsics/intrinsic-raw_eq-const.rs
+++ b/src/test/ui/intrinsics/intrinsic-raw_eq-const.rs
@@ -2,7 +2,6 @@
#![feature(core_intrinsics)]
#![feature(const_intrinsic_raw_eq)]
-#![deny(const_err)]
pub fn main() {
use std::intrinsics::raw_eq;
diff --git a/src/test/ui/intrinsics/intrinsics-integer.rs b/src/test/ui/intrinsics/intrinsics-integer.rs
index bac6c8d87..88bf42b68 100644
--- a/src/test/ui/intrinsics/intrinsics-integer.rs
+++ b/src/test/ui/intrinsics/intrinsics-integer.rs
@@ -1,15 +1,21 @@
// 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;
}
}
diff --git a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
index 255151a96..ec3860a32 100644
--- a/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
+++ b/src/test/ui/intrinsics/panic-uninitialized-zeroed.rs
@@ -1,6 +1,5 @@
// run-pass
// needs-unwind
-// ignore-wasm32-bare compiled with panic=abort by default
// revisions: mir thir strict
// [thir]compile-flags: -Zthir-unsafeck
// [strict]compile-flags: -Zstrict-init-checks
@@ -8,7 +7,7 @@
// This test checks panic emitted from `mem::{uninitialized,zeroed}`.
-#![feature(never_type, arbitrary_enum_discriminant)]
+#![feature(never_type)]
#![allow(deprecated, invalid_value)]
use std::{
@@ -35,6 +34,12 @@ enum OneVariant_NonZero {
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)]
@@ -64,6 +69,7 @@ enum ZeroIsValid {
One(NonNull<()>) = 1,
}
+#[track_caller]
fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
let err = panic::catch_unwind(op).err();
assert_eq!(
@@ -72,6 +78,15 @@ fn test_panic_msg<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
);
}
+#[track_caller]
+fn test_panic_msg_only_if_strict<T>(op: impl (FnOnce() -> T) + panic::UnwindSafe, msg: &str) {
+ let err = panic::catch_unwind(op).err();
+ assert_eq!(
+ err.as_ref().and_then(|a| a.downcast_ref::<&str>()),
+ if cfg!(strict) { Some(&msg) } else { None },
+ );
+}
+
fn main() {
unsafe {
// Uninhabited types
@@ -140,92 +155,216 @@ fn main() {
"attempted to instantiate uninhabited type `[Bar; 2]`"
);
- // Types that do not like zero-initialziation
+ // Types that don't allow either.
test_panic_msg(
- || mem::uninitialized::<fn()>(),
- "attempted to leave type `fn()` uninitialized, which is invalid"
+ || mem::zeroed::<&i32>(),
+ "attempted to zero-initialize type `&i32`, which is invalid"
);
test_panic_msg(
- || mem::zeroed::<fn()>(),
- "attempted to zero-initialize type `fn()`, which is invalid"
+ || mem::uninitialized::<&i32>(),
+ "attempted to leave type `&i32` uninitialized, which is invalid"
);
test_panic_msg(
- || mem::uninitialized::<*const dyn Send>(),
- "attempted to leave type `*const dyn core::marker::Send` uninitialized, which is invalid"
+ || 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::<(NonNull<u32>, u32, u32)>(),
- "attempted to leave type `(core::ptr::non_null::NonNull<u32>, u32, u32)` uninitialized, \
+ || 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::<(NonNull<u32>, u32, u32)>(),
- "attempted to zero-initialize type `(core::ptr::non_null::NonNull<u32>, u32, u32)`, \
+ || 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::uninitialized::<OneVariant_NonZero>(),
- "attempted to leave type `OneVariant_NonZero` uninitialized, \
+ || 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"
);
- test_panic_msg(
- || mem::uninitialized::<NoNullVariant>(),
- "attempted to leave type `NoNullVariant` 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(
- || mem::zeroed::<NoNullVariant>(),
- "attempted to zero-initialize type `NoNullVariant`, \
- which is invalid"
+ test_panic_msg_only_if_strict(
+ || mem::uninitialized::<*const ()>(),
+ "attempted to leave type `*const ()` uninitialized, which is invalid"
);
- // Types that can be zero, but not uninit.
- test_panic_msg(
- || mem::uninitialized::<bool>(),
- "attempted to leave type `bool` 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"
);
- // Some things that should work.
let _val = mem::zeroed::<bool>();
- let _val = mem::zeroed::<LR>();
- let _val = mem::zeroed::<ManuallyDrop<LR>>();
+ 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]>();
@@ -234,59 +373,5 @@ fn main() {
let _val = mem::uninitialized::<[!; 0]>();
let _val = mem::uninitialized::<()>();
let _val = mem::uninitialized::<ZeroSized>();
-
- if cfg!(strict) {
- test_panic_msg(
- || mem::uninitialized::<i32>(),
- "attempted to leave type `i32` uninitialized, which is invalid"
- );
-
- test_panic_msg(
- || mem::uninitialized::<*const ()>(),
- "attempted to leave type `*const ()` uninitialized, which is invalid"
- );
-
- test_panic_msg(
- || mem::uninitialized::<[i32; 1]>(),
- "attempted to leave type `[i32; 1]` uninitialized, which is invalid"
- );
-
- test_panic_msg(
- || mem::zeroed::<NonNull<()>>(),
- "attempted to zero-initialize type `core::ptr::non_null::NonNull<()>`, which is invalid"
- );
-
- test_panic_msg(
- || mem::zeroed::<[NonNull<()>; 1]>(),
- "attempted to zero-initialize type `[core::ptr::non_null::NonNull<()>; 1]`, which is invalid"
- );
-
- // FIXME(#66151) we conservatively do not error here yet (by default).
- test_panic_msg(
- || mem::zeroed::<LR_NonZero>(),
- "attempted to zero-initialize type `LR_NonZero`, which is invalid"
- );
-
- test_panic_msg(
- || mem::zeroed::<ManuallyDrop<LR_NonZero>>(),
- "attempted to zero-initialize type `core::mem::manually_drop::ManuallyDrop<LR_NonZero>`, \
- which is invalid"
- );
- } else {
- // These are UB because they have not been officially blessed, but we await the resolution
- // of <https://github.com/rust-lang/unsafe-code-guidelines/issues/71> before doing
- // anything about that.
- let _val = mem::uninitialized::<i32>();
- let _val = mem::uninitialized::<*const ()>();
-
- // These are UB, but best to test them to ensure we don't become unintentionally
- // stricter.
-
- // It's currently unchecked to create invalid enums and values inside arrays.
- let _val = mem::zeroed::<LR_NonZero>();
- let _val = mem::zeroed::<[LR_NonZero; 1]>();
- let _val = mem::zeroed::<[NonNull<()>; 1]>();
- let _val = mem::uninitialized::<[NonNull<()>; 1]>();
- }
}
}
diff --git a/src/test/ui/intrinsics/safe-intrinsic-mismatch.rs b/src/test/ui/intrinsics/safe-intrinsic-mismatch.rs
new file mode 100644
index 000000000..50e12eaeb
--- /dev/null
+++ b/src/test/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/src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr b/src/test/ui/intrinsics/safe-intrinsic-mismatch.stderr
new file mode 100644
index 000000000..0c2f3be49
--- /dev/null
+++ b/src/test/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
+