summaryrefslogtreecommitdiffstats
path: root/tests/ui/consts/const-eval
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/consts/const-eval')
-rw-r--r--tests/ui/consts/const-eval/assign-to-static-within-other-static.rs12
-rw-r--r--tests/ui/consts/const-eval/assign-to-static-within-other-static.stderr9
-rw-r--r--tests/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs20
-rw-r--r--tests/ui/consts/const-eval/auxiliary/stability.rs10
-rw-r--r--tests/ui/consts/const-eval/conditional_array_execution.rs8
-rw-r--r--tests/ui/consts/const-eval/conditional_array_execution.stderr9
-rw-r--r--tests/ui/consts/const-eval/const-eval-intrinsic-promotion.rs6
-rw-r--r--tests/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr13
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-2.rs20
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-2.stderr21
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-3.rs27
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-3.stderr9
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-3b.rs26
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-3b.stderr23
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-4.rs21
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-4.stderr9
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-4b.rs26
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow-4b.stderr35
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow2.rs69
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow2.stderr51
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow2b.rs69
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow2b.stderr51
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow2c.rs69
-rw-r--r--tests/ui/consts/const-eval/const-eval-overflow2c.stderr51
-rw-r--r--tests/ui/consts/const-eval/const-eval-query-stack.rs22
-rw-r--r--tests/ui/consts/const-eval/const-eval-query-stack.stderr13
-rw-r--r--tests/ui/consts/const-eval/const-eval-span.rs14
-rw-r--r--tests/ui/consts/const-eval/const-eval-span.stderr9
-rw-r--r--tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr258
-rw-r--r--tests/ui/consts/const-eval/const-pointer-values-in-various-types.rs114
-rw-r--r--tests/ui/consts/const-eval/const_fn_ptr.rs36
-rw-r--r--tests/ui/consts/const-eval/const_fn_ptr.stderr20
-rw-r--r--tests/ui/consts/const-eval/const_fn_ptr_fail.rs12
-rw-r--r--tests/ui/consts/const-eval/const_fn_ptr_fail.stderr10
-rw-r--r--tests/ui/consts/const-eval/const_fn_ptr_fail2.rs20
-rw-r--r--tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr45
-rw-r--r--tests/ui/consts/const-eval/const_let.rs29
-rw-r--r--tests/ui/consts/const-eval/const_let.stderr35
-rw-r--r--tests/ui/consts/const-eval/const_panic.rs40
-rw-r--r--tests/ui/consts/const-eval/const_panic.stderr99
-rw-r--r--tests/ui/consts/const-eval/const_panic_2021.rs34
-rw-r--r--tests/ui/consts/const-eval/const_panic_2021.stderr83
-rw-r--r--tests/ui/consts/const-eval/const_panic_libcore_bin.rs25
-rw-r--r--tests/ui/consts/const-eval/const_panic_libcore_bin.stderr27
-rw-r--r--tests/ui/consts/const-eval/const_panic_stability.e2018.stderr16
-rw-r--r--tests/ui/consts/const-eval/const_panic_stability.e2021.stderr13
-rw-r--r--tests/ui/consts/const-eval/const_panic_stability.rs17
-rw-r--r--tests/ui/consts/const-eval/const_panic_track_caller.rs22
-rw-r--r--tests/ui/consts/const-eval/const_panic_track_caller.stderr20
-rw-r--r--tests/ui/consts/const-eval/const_prop_errors.rs14
-rw-r--r--tests/ui/consts/const-eval/const_raw_ptr_ops.rs6
-rw-r--r--tests/ui/consts/const-eval/const_raw_ptr_ops.stderr29
-rw-r--r--tests/ui/consts/const-eval/const_raw_ptr_ops2.rs10
-rw-r--r--tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr15
-rw-r--r--tests/ui/consts/const-eval/const_signed_pat.rs9
-rw-r--r--tests/ui/consts/const-eval/dangling.rs10
-rw-r--r--tests/ui/consts/const-eval/dangling.stderr9
-rw-r--r--tests/ui/consts/const-eval/dont_promote_unstable_const_fn.rs24
-rw-r--r--tests/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr43
-rw-r--r--tests/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs10
-rw-r--r--tests/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr24
-rw-r--r--tests/ui/consts/const-eval/double_check.rs25
-rw-r--r--tests/ui/consts/const-eval/double_check2.rs32
-rw-r--r--tests/ui/consts/const-eval/duration_conversion.rs16
-rw-r--r--tests/ui/consts/const-eval/enum_discr.rs25
-rw-r--r--tests/ui/consts/const-eval/erroneous-const.rs21
-rw-r--r--tests/ui/consts/const-eval/erroneous-const.stderr15
-rw-r--r--tests/ui/consts/const-eval/erroneous-const2.rs19
-rw-r--r--tests/ui/consts/const-eval/erroneous-const2.stderr15
-rw-r--r--tests/ui/consts/const-eval/extern_fat_pointer.rs13
-rw-r--r--tests/ui/consts/const-eval/format.rs13
-rw-r--r--tests/ui/consts/const-eval/format.stderr95
-rw-r--r--tests/ui/consts/const-eval/generic-slice.rs31
-rw-r--r--tests/ui/consts/const-eval/generic-slice.stderr30
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs15
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr20
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs19
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.rs18
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.stderr8
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_transient.rs19
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr14
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr14
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs10
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.rs9
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.stderr8
-rw-r--r--tests/ui/consts/const-eval/heap/alloc_intrinsic_zero_sized.rs16
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic.rs36
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs22
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr15
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.rs13
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr9
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.rs29
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.stderr27
-rw-r--r--tests/ui/consts/const-eval/heap/dealloc_intrinsic_zero_sized.rs17
-rw-r--r--tests/ui/consts/const-eval/ice-generic-assoc-const.rs16
-rw-r--r--tests/ui/consts/const-eval/ice-packed.rs21
-rw-r--r--tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs21
-rw-r--r--tests/ui/consts/const-eval/index-out-of-bounds-never-type.stderr15
-rw-r--r--tests/ui/consts/const-eval/index_out_of_bounds.rs4
-rw-r--r--tests/ui/consts/const-eval/index_out_of_bounds.stderr9
-rw-r--r--tests/ui/consts/const-eval/index_out_of_bounds_propagated.rs6
-rw-r--r--tests/ui/consts/const-eval/index_out_of_bounds_propagated.stderr10
-rw-r--r--tests/ui/consts/const-eval/infinite_loop.rs12
-rw-r--r--tests/ui/consts/const-eval/infinite_loop.stderr9
-rw-r--r--tests/ui/consts/const-eval/issue-100878.rs8
-rw-r--r--tests/ui/consts/const-eval/issue-104390.rs10
-rw-r--r--tests/ui/consts/const-eval/issue-104390.stderr65
-rw-r--r--tests/ui/consts/const-eval/issue-43197.rs11
-rw-r--r--tests/ui/consts/const-eval/issue-43197.stderr15
-rw-r--r--tests/ui/consts/const-eval/issue-44578.rs27
-rw-r--r--tests/ui/consts/const-eval/issue-44578.stderr39
-rw-r--r--tests/ui/consts/const-eval/issue-47971.rs9
-rw-r--r--tests/ui/consts/const-eval/issue-49296.rs14
-rw-r--r--tests/ui/consts/const-eval/issue-49296.stderr9
-rw-r--r--tests/ui/consts/const-eval/issue-50706.rs37
-rw-r--r--tests/ui/consts/const-eval/issue-50814-2.rs34
-rw-r--r--tests/ui/consts/const-eval/issue-50814-2.stderr21
-rw-r--r--tests/ui/consts/const-eval/issue-50814.rs26
-rw-r--r--tests/ui/consts/const-eval/issue-50814.stderr21
-rw-r--r--tests/ui/consts/const-eval/issue-51300.rs31
-rw-r--r--tests/ui/consts/const-eval/issue-52475.rs11
-rw-r--r--tests/ui/consts/const-eval/issue-52475.stderr9
-rw-r--r--tests/ui/consts/const-eval/issue-53157.rs13
-rw-r--r--tests/ui/consts/const-eval/issue-53401.rs11
-rw-r--r--tests/ui/consts/const-eval/issue-55541.rs27
-rw-r--r--tests/ui/consts/const-eval/issue-64908.rs20
-rw-r--r--tests/ui/consts/const-eval/issue-64970.rs15
-rw-r--r--tests/ui/consts/const-eval/issue-65394.rs13
-rw-r--r--tests/ui/consts/const-eval/issue-65394.stderr22
-rw-r--r--tests/ui/consts/const-eval/issue-70723.rs3
-rw-r--r--tests/ui/consts/const-eval/issue-70723.stderr9
-rw-r--r--tests/ui/consts/const-eval/issue-70804-fn-subtyping.rs9
-rw-r--r--tests/ui/consts/const-eval/issue-84957-const-str-as-bytes.rs28
-rw-r--r--tests/ui/consts/const-eval/issue-85155.rs21
-rw-r--r--tests/ui/consts/const-eval/issue-85155.stderr15
-rw-r--r--tests/ui/consts/const-eval/issue-85907.rs7
-rw-r--r--tests/ui/consts/const-eval/issue-85907.stderr10
-rw-r--r--tests/ui/consts/const-eval/issue-91827-extern-types.rs56
-rw-r--r--tests/ui/consts/const-eval/livedrop.rs17
-rw-r--r--tests/ui/consts/const-eval/livedrop.stderr12
-rw-r--r--tests/ui/consts/const-eval/match-test-ptr-null.rs12
-rw-r--r--tests/ui/consts/const-eval/match-test-ptr-null.stderr11
-rw-r--r--tests/ui/consts/const-eval/mod-static-with-const-fn.rs22
-rw-r--r--tests/ui/consts/const-eval/mod-static-with-const-fn.stderr9
-rw-r--r--tests/ui/consts/const-eval/no_lint_for_statically_known_error.rs18
-rw-r--r--tests/ui/consts/const-eval/nrvo.rs26
-rw-r--r--tests/ui/consts/const-eval/panic-assoc-never-type.rs15
-rw-r--r--tests/ui/consts/const-eval/panic-assoc-never-type.stderr23
-rw-r--r--tests/ui/consts/const-eval/panic-never-type.rs9
-rw-r--r--tests/ui/consts/const-eval/panic-never-type.stderr11
-rw-r--r--tests/ui/consts/const-eval/partial_ptr_overwrite.rs14
-rw-r--r--tests/ui/consts/const-eval/partial_ptr_overwrite.stderr12
-rw-r--r--tests/ui/consts/const-eval/promote-static.rs14
-rw-r--r--tests/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs5
-rw-r--r--tests/ui/consts/const-eval/promoted_const_fn_fail.rs20
-rw-r--r--tests/ui/consts/const-eval/promoted_const_fn_fail.stderr14
-rw-r--r--tests/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs22
-rw-r--r--tests/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr14
-rw-r--r--tests/ui/consts/const-eval/promoted_errors.noopt.stderr44
-rw-r--r--tests/ui/consts/const-eval/promoted_errors.opt.stderr44
-rw-r--r--tests/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr44
-rw-r--r--tests/ui/consts/const-eval/promoted_errors.rs52
-rw-r--r--tests/ui/consts/const-eval/promoted_raw_ptr_ops.rs10
-rw-r--r--tests/ui/consts/const-eval/promoted_raw_ptr_ops.stderr47
-rw-r--r--tests/ui/consts/const-eval/raw-bytes.32bit.stderr596
-rw-r--r--tests/ui/consts/const-eval/raw-bytes.64bit.stderr596
-rw-r--r--tests/ui/consts/const-eval/raw-bytes.rs263
-rw-r--r--tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr24
-rw-r--r--tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr24
-rw-r--r--tests/ui/consts/const-eval/ref_to_int_match.rs26
-rw-r--r--tests/ui/consts/const-eval/shift_overflow.rs9
-rw-r--r--tests/ui/consts/const-eval/shift_overflow.stderr9
-rw-r--r--tests/ui/consts/const-eval/simd/insert_extract.rs70
-rw-r--r--tests/ui/consts/const-eval/simple_with_undef.rs6
-rw-r--r--tests/ui/consts/const-eval/size-of-t.rs13
-rw-r--r--tests/ui/consts/const-eval/size-of-t.stderr11
-rw-r--r--tests/ui/consts/const-eval/strlen.rs31
-rw-r--r--tests/ui/consts/const-eval/transmute-const-promotion.rs6
-rw-r--r--tests/ui/consts/const-eval/transmute-const-promotion.stderr14
-rw-r--r--tests/ui/consts/const-eval/transmute-const.32bit.stderr14
-rw-r--r--tests/ui/consts/const-eval/transmute-const.64bit.stderr14
-rw-r--r--tests/ui/consts/const-eval/transmute-const.rs7
-rw-r--r--tests/ui/consts/const-eval/ub-enum-overwrite.rs18
-rw-r--r--tests/ui/consts/const-eval/ub-enum-overwrite.stderr9
-rw-r--r--tests/ui/consts/const-eval/ub-enum.32bit.stderr121
-rw-r--r--tests/ui/consts/const-eval/ub-enum.64bit.stderr121
-rw-r--r--tests/ui/consts/const-eval/ub-enum.rs102
-rw-r--r--tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr59
-rw-r--r--tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr59
-rw-r--r--tests/ui/consts/const-eval/ub-incorrect-vtable.rs96
-rw-r--r--tests/ui/consts/const-eval/ub-int-array.32bit.stderr21
-rw-r--r--tests/ui/consts/const-eval/ub-int-array.64bit.stderr21
-rw-r--r--tests/ui/consts/const-eval/ub-int-array.rs63
-rw-r--r--tests/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr9
-rw-r--r--tests/ui/consts/const-eval/ub-nonnull.rs59
-rw-r--r--tests/ui/consts/const-eval/ub-nonnull.stderr81
-rw-r--r--tests/ui/consts/const-eval/ub-ref-ptr.rs71
-rw-r--r--tests/ui/consts/const-eval/ub-ref-ptr.stderr186
-rw-r--r--tests/ui/consts/const-eval/ub-uninhabit.rs25
-rw-r--r--tests/ui/consts/const-eval/ub-uninhabit.stderr32
-rw-r--r--tests/ui/consts/const-eval/ub-upvars.32bit.stderr14
-rw-r--r--tests/ui/consts/const-eval/ub-upvars.64bit.stderr14
-rw-r--r--tests/ui/consts/const-eval/ub-upvars.rs12
-rw-r--r--tests/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr9
-rw-r--r--tests/ui/consts/const-eval/ub-wide-ptr.rs159
-rw-r--r--tests/ui/consts/const-eval/ub-wide-ptr.stderr297
-rw-r--r--tests/ui/consts/const-eval/union-const-eval-field.rs38
-rw-r--r--tests/ui/consts/const-eval/union-const-eval-field.stderr21
-rw-r--r--tests/ui/consts/const-eval/union-ice.rs48
-rw-r--r--tests/ui/consts/const-eval/union-ice.stderr21
-rw-r--r--tests/ui/consts/const-eval/union-ub.32bit.stderr20
-rw-r--r--tests/ui/consts/const-eval/union-ub.64bit.stderr20
-rw-r--r--tests/ui/consts/const-eval/union-ub.rs43
-rw-r--r--tests/ui/consts/const-eval/union_promotion.rs11
-rw-r--r--tests/ui/consts/const-eval/union_promotion.stderr16
-rw-r--r--tests/ui/consts/const-eval/unused-broken-const.rs8
-rw-r--r--tests/ui/consts/const-eval/unused-broken-const.stderr9
-rw-r--r--tests/ui/consts/const-eval/unwind-abort.rs12
-rw-r--r--tests/ui/consts/const-eval/unwind-abort.stderr21
-rw-r--r--tests/ui/consts/const-eval/valid-const.rs17
-rw-r--r--tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr61
-rw-r--r--tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr61
-rw-r--r--tests/ui/consts/const-eval/validate_uninhabited_zsts.rs28
-rw-r--r--tests/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs28
-rw-r--r--tests/ui/consts/const-eval/zst_operand_eval.rs5
225 files changed, 7807 insertions, 0 deletions
diff --git a/tests/ui/consts/const-eval/assign-to-static-within-other-static.rs b/tests/ui/consts/const-eval/assign-to-static-within-other-static.rs
new file mode 100644
index 000000000..ecf97223f
--- /dev/null
+++ b/tests/ui/consts/const-eval/assign-to-static-within-other-static.rs
@@ -0,0 +1,12 @@
+// New test for #53818: modifying static memory at compile-time is not allowed.
+// The test should never compile successfully
+
+use std::cell::UnsafeCell;
+
+static mut FOO: u32 = 42;
+static BOO: () = unsafe {
+ FOO = 5;
+ //~^ could not evaluate static initializer [E0080]
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/assign-to-static-within-other-static.stderr b/tests/ui/consts/const-eval/assign-to-static-within-other-static.stderr
new file mode 100644
index 000000000..4b6784acf
--- /dev/null
+++ b/tests/ui/consts/const-eval/assign-to-static-within-other-static.stderr
@@ -0,0 +1,9 @@
+error[E0080]: could not evaluate static initializer
+ --> $DIR/assign-to-static-within-other-static.rs:8:5
+ |
+LL | FOO = 5;
+ | ^^^^^^^ modifying a static's initial value from another static's initializer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs b/tests/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs
new file mode 100644
index 000000000..bdeaa0cd3
--- /dev/null
+++ b/tests/ui/consts/const-eval/auxiliary/post_monomorphization_error.rs
@@ -0,0 +1,20 @@
+// Auxiliary crate used for testing post-monomorphization errors cross-crate.
+// It duplicates the setup used in `stdarch` to validate its intrinsics' const arguments.
+
+struct ValidateConstImm<const IMM: i32, const MIN: i32, const MAX: i32>;
+impl<const IMM: i32, const MIN: i32, const MAX: i32> ValidateConstImm<IMM, MIN, MAX> {
+ pub(crate) const VALID: () = {
+ let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize);
+ };
+}
+
+macro_rules! static_assert_imm1 {
+ ($imm:ident) => {
+ let _ = $crate::ValidateConstImm::<$imm, 0, { (1 << 1) - 1 }>::VALID;
+ };
+}
+
+// This function triggers an error whenever the const argument does not fit in 1-bit.
+pub fn stdarch_intrinsic<const IMM1: i32>() {
+ static_assert_imm1!(IMM1);
+}
diff --git a/tests/ui/consts/const-eval/auxiliary/stability.rs b/tests/ui/consts/const-eval/auxiliary/stability.rs
new file mode 100644
index 000000000..e61595518
--- /dev/null
+++ b/tests/ui/consts/const-eval/auxiliary/stability.rs
@@ -0,0 +1,10 @@
+// Crate that exports a const fn. Used for testing cross-crate.
+
+#![crate_type="rlib"]
+#![stable(feature = "rust1", since = "1.0.0")]
+
+#![feature(staged_api)]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature="foo", issue = "none")]
+pub const fn foo() -> u32 { 42 }
diff --git a/tests/ui/consts/const-eval/conditional_array_execution.rs b/tests/ui/consts/const-eval/conditional_array_execution.rs
new file mode 100644
index 000000000..27d5383d6
--- /dev/null
+++ b/tests/ui/consts/const-eval/conditional_array_execution.rs
@@ -0,0 +1,8 @@
+const X: u32 = 5;
+const Y: u32 = 6;
+const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+//~^ ERROR constant
+
+fn main() {
+ println!("{}", FOO);
+}
diff --git a/tests/ui/consts/const-eval/conditional_array_execution.stderr b/tests/ui/consts/const-eval/conditional_array_execution.stderr
new file mode 100644
index 000000000..c3401fbae
--- /dev/null
+++ b/tests/ui/consts/const-eval/conditional_array_execution.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/conditional_array_execution.rs:3:19
+ |
+LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize];
+ | ^^^^^ attempt to compute `5_u32 - 6_u32`, which would overflow
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const-eval-intrinsic-promotion.rs b/tests/ui/consts/const-eval/const-eval-intrinsic-promotion.rs
new file mode 100644
index 000000000..bdcf53785
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-intrinsic-promotion.rs
@@ -0,0 +1,6 @@
+#![feature(core_intrinsics)]
+fn main() {
+ // Test that calls to intrinsics are never promoted
+ let x: &'static usize =
+ &std::intrinsics::size_of::<i32>(); //~ ERROR temporary value dropped while borrowed
+}
diff --git a/tests/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr b/tests/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr
new file mode 100644
index 000000000..ed6a6ee6e
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-intrinsic-promotion.stderr
@@ -0,0 +1,13 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/const-eval-intrinsic-promotion.rs:5:10
+ |
+LL | let x: &'static usize =
+ | -------------- type annotation requires that borrow lasts for `'static`
+LL | &std::intrinsics::size_of::<i32>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-2.rs b/tests/ui/consts/const-eval/const-eval-overflow-2.rs
new file mode 100644
index 000000000..535d91359
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-2.rs
@@ -0,0 +1,20 @@
+// Evaluation of constants in refutable patterns goes through
+// different compiler control-flow paths.
+
+#![allow(unused_imports, warnings)]
+
+use std::fmt;
+use std::{i8, i16, i32, i64, isize};
+use std::{u8, u16, u32, u64, usize};
+
+const NEG_128: i8 = -128;
+const NEG_NEG_128: i8 = -NEG_128; //~ ERROR constant
+
+fn main() {
+ match -128i8 {
+ NEG_NEG_128 => println!("A"),
+ //~^ ERROR could not evaluate constant pattern
+ //~| ERROR could not evaluate constant pattern
+ _ => println!("B"),
+ }
+}
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-2.stderr b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr
new file mode 100644
index 000000000..7b1fe49d4
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-2.stderr
@@ -0,0 +1,21 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow-2.rs:11:25
+ |
+LL | const NEG_NEG_128: i8 = -NEG_128;
+ | ^^^^^^^^ attempt to negate `i8::MIN`, which would overflow
+
+error: could not evaluate constant pattern
+ --> $DIR/const-eval-overflow-2.rs:15:9
+ |
+LL | NEG_NEG_128 => println!("A"),
+ | ^^^^^^^^^^^
+
+error: could not evaluate constant pattern
+ --> $DIR/const-eval-overflow-2.rs:15:9
+ |
+LL | NEG_NEG_128 => println!("A"),
+ | ^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3.rs b/tests/ui/consts/const-eval/const-eval-overflow-3.rs
new file mode 100644
index 000000000..bcc966dc9
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-3.rs
@@ -0,0 +1,27 @@
+// Evaluation of constants in array-elem count goes through different
+// compiler control-flow paths.
+//
+// This test is checking the count in an array expression.
+
+
+
+
+
+
+
+#![allow(unused_imports)]
+
+use std::fmt;
+
+const A_I8_I
+ : [u32; (i8::MAX as usize) + 1]
+ = [0; (i8::MAX + 1) as usize];
+//~^ ERROR evaluation of constant value failed
+
+fn main() {
+ foo(&A_I8_I[..]);
+}
+
+fn foo<T:fmt::Debug>(x: T) {
+ println!("{:?}", x);
+}
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3.stderr
new file mode 100644
index 000000000..73f421b5b
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-3.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow-3.rs:18:11
+ |
+LL | = [0; (i8::MAX + 1) as usize];
+ | ^^^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3b.rs b/tests/ui/consts/const-eval/const-eval-overflow-3b.rs
new file mode 100644
index 000000000..480069e67
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-3b.rs
@@ -0,0 +1,26 @@
+// Evaluation of constants in array-elem count goes through different
+// compiler control-flow paths.
+//
+// This test is checking the count in an array expression.
+//
+// This is a variation of another such test, but in this case the
+// types for the left- and right-hand sides of the addition do not
+// match (as well as overflow).
+
+#![allow(unused_imports)]
+
+use std::fmt;
+
+const A_I8_I
+ : [u32; (i8::MAX as usize) + 1]
+ = [0; (i8::MAX + 1u8) as usize];
+//~^ ERROR mismatched types
+//~| ERROR cannot add `u8` to `i8`
+
+fn main() {
+ foo(&A_I8_I[..]);
+}
+
+fn foo<T:fmt::Debug>(x: T) {
+ println!("{:?}", x);
+}
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr
new file mode 100644
index 000000000..f19917001
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-3b.stderr
@@ -0,0 +1,23 @@
+error[E0308]: mismatched types
+ --> $DIR/const-eval-overflow-3b.rs:16:22
+ |
+LL | = [0; (i8::MAX + 1u8) as usize];
+ | ^^^ expected `i8`, found `u8`
+
+error[E0277]: cannot add `u8` to `i8` in const contexts
+ --> $DIR/const-eval-overflow-3b.rs:16:20
+ |
+LL | = [0; (i8::MAX + 1u8) as usize];
+ | ^ no implementation for `i8 + u8`
+ |
+ = help: the trait `~const Add<u8>` is not implemented for `i8`
+ = help: the following other types implement trait `Add<Rhs>`:
+ <&'a i8 as Add<i8>>
+ <&i8 as Add<&i8>>
+ <i8 as Add<&i8>>
+ <i8 as Add>
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4.rs b/tests/ui/consts/const-eval/const-eval-overflow-4.rs
new file mode 100644
index 000000000..762c7a968
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-4.rs
@@ -0,0 +1,21 @@
+// Evaluation of constants in array-elem count goes through different
+// compiler control-flow paths.
+//
+// This test is checking the count in an array type.
+
+#![allow(unused_imports)]
+
+use std::fmt;
+
+const A_I8_T
+ : [u32; (i8::MAX as i8 + 1i8) as usize]
+ //~^ ERROR evaluation of constant value failed
+ = [0; (i8::MAX as usize) + 1];
+
+fn main() {
+ foo(&A_I8_T[..]);
+}
+
+fn foo<T:fmt::Debug>(x: T) {
+ println!("{:?}", x);
+}
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4.stderr
new file mode 100644
index 000000000..94f419319
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-4.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow-4.rs:11:13
+ |
+LL | : [u32; (i8::MAX as i8 + 1i8) as usize]
+ | ^^^^^^^^^^^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.rs b/tests/ui/consts/const-eval/const-eval-overflow-4b.rs
new file mode 100644
index 000000000..ce9c980de
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.rs
@@ -0,0 +1,26 @@
+// Evaluation of constants in array-elem count goes through different
+// compiler control-flow paths.
+//
+// This test is checking the count in an array type.
+
+#![allow(unused_imports)]
+
+const A_I8_T
+ : [u32; (i8::MAX as i8 + 1u8) as usize]
+ //~^ ERROR mismatched types
+ //~| expected `i8`, found `u8`
+ //~| ERROR cannot add `u8` to `i8`
+ = [0; (i8::MAX as usize) + 1];
+
+
+const A_CHAR_USIZE
+ : [u32; 5u8 as char as usize]
+ = [0; 5];
+
+
+const A_BAD_CHAR_USIZE
+ : [u32; 5i8 as char as usize]
+ //~^ ERROR only `u8` can be cast as `char`, not `i8`
+ = [0; 5];
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr
new file mode 100644
index 000000000..1f8e40231
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow-4b.stderr
@@ -0,0 +1,35 @@
+error[E0308]: mismatched types
+ --> $DIR/const-eval-overflow-4b.rs:9:30
+ |
+LL | : [u32; (i8::MAX as i8 + 1u8) as usize]
+ | ^^^ expected `i8`, found `u8`
+
+error[E0277]: cannot add `u8` to `i8` in const contexts
+ --> $DIR/const-eval-overflow-4b.rs:9:28
+ |
+LL | : [u32; (i8::MAX as i8 + 1u8) as usize]
+ | ^ no implementation for `i8 + u8`
+ |
+ = help: the trait `~const Add<u8>` is not implemented for `i8`
+ = help: the following other types implement trait `Add<Rhs>`:
+ <&'a i8 as Add<i8>>
+ <&i8 as Add<&i8>>
+ <i8 as Add<&i8>>
+ <i8 as Add>
+
+error[E0604]: only `u8` can be cast as `char`, not `i8`
+ --> $DIR/const-eval-overflow-4b.rs:22:13
+ |
+LL | : [u32; 5i8 as char as usize]
+ | ^^^^^^^^^^^ invalid cast
+ |
+help: try casting from `u8` instead
+ --> $DIR/const-eval-overflow-4b.rs:22:13
+ |
+LL | : [u32; 5i8 as char as usize]
+ | ^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0308, E0604.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/const-eval/const-eval-overflow2.rs b/tests/ui/consts/const-eval/const-eval-overflow2.rs
new file mode 100644
index 000000000..1676f7c2a
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow2.rs
@@ -0,0 +1,69 @@
+#![allow(unused_imports)]
+
+// Note: the relevant lint pass here runs before some of the constant
+// evaluation below (e.g., that performed by codegen and llvm), so if you
+// change this warn to a deny, then the compiler will exit before
+// those errors are detected.
+
+use std::fmt;
+
+const VALS_I8: (i8,) =
+ (
+ i8::MIN - 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_I16: (i16,) =
+ (
+ i16::MIN - 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_I32: (i32,) =
+ (
+ i32::MIN - 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_I64: (i64,) =
+ (
+ i64::MIN - 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U8: (u8,) =
+ (
+ u8::MIN - 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U16: (u16,) = (
+ u16::MIN - 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U32: (u32,) = (
+ u32::MIN - 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U64: (u64,) =
+ (
+ u64::MIN - 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+fn main() {
+ foo(VALS_I8);
+ foo(VALS_I16);
+ foo(VALS_I32);
+ foo(VALS_I64);
+
+ foo(VALS_U8);
+ foo(VALS_U16);
+ foo(VALS_U32);
+ foo(VALS_U64);
+}
+
+fn foo<T>(_: T) {
+}
diff --git a/tests/ui/consts/const-eval/const-eval-overflow2.stderr b/tests/ui/consts/const-eval/const-eval-overflow2.stderr
new file mode 100644
index 000000000..341c15daf
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow2.stderr
@@ -0,0 +1,51 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2.rs:12:6
+ |
+LL | i8::MIN - 1,
+ | ^^^^^^^^^^^ attempt to compute `i8::MIN - 1_i8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2.rs:18:6
+ |
+LL | i16::MIN - 1,
+ | ^^^^^^^^^^^^ attempt to compute `i16::MIN - 1_i16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2.rs:24:6
+ |
+LL | i32::MIN - 1,
+ | ^^^^^^^^^^^^ attempt to compute `i32::MIN - 1_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2.rs:30:6
+ |
+LL | i64::MIN - 1,
+ | ^^^^^^^^^^^^ attempt to compute `i64::MIN - 1_i64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2.rs:36:6
+ |
+LL | u8::MIN - 1,
+ | ^^^^^^^^^^^ attempt to compute `0_u8 - 1_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2.rs:41:6
+ |
+LL | u16::MIN - 1,
+ | ^^^^^^^^^^^^ attempt to compute `0_u16 - 1_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2.rs:46:6
+ |
+LL | u32::MIN - 1,
+ | ^^^^^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2.rs:52:6
+ |
+LL | u64::MIN - 1,
+ | ^^^^^^^^^^^^ attempt to compute `0_u64 - 1_u64`, which would overflow
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const-eval-overflow2b.rs b/tests/ui/consts/const-eval/const-eval-overflow2b.rs
new file mode 100644
index 000000000..59d1df568
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow2b.rs
@@ -0,0 +1,69 @@
+#![allow(unused_imports)]
+
+// Note: the relevant lint pass here runs before some of the constant
+// evaluation below (e.g., that performed by codegen and llvm), so if you
+// change this warn to a deny, then the compiler will exit before
+// those errors are detected.
+
+use std::fmt;
+
+const VALS_I8: (i8,) =
+ (
+ i8::MAX + 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_I16: (i16,) =
+ (
+ i16::MAX + 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_I32: (i32,) =
+ (
+ i32::MAX + 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_I64: (i64,) =
+ (
+ i64::MAX + 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U8: (u8,) =
+ (
+ u8::MAX + 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U16: (u16,) = (
+ u16::MAX + 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U32: (u32,) = (
+ u32::MAX + 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U64: (u64,) =
+ (
+ u64::MAX + 1,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+fn main() {
+ foo(VALS_I8);
+ foo(VALS_I16);
+ foo(VALS_I32);
+ foo(VALS_I64);
+
+ foo(VALS_U8);
+ foo(VALS_U16);
+ foo(VALS_U32);
+ foo(VALS_U64);
+}
+
+fn foo<T>(_: T) {
+}
diff --git a/tests/ui/consts/const-eval/const-eval-overflow2b.stderr b/tests/ui/consts/const-eval/const-eval-overflow2b.stderr
new file mode 100644
index 000000000..e661836b4
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow2b.stderr
@@ -0,0 +1,51 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2b.rs:12:6
+ |
+LL | i8::MAX + 1,
+ | ^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2b.rs:18:6
+ |
+LL | i16::MAX + 1,
+ | ^^^^^^^^^^^^ attempt to compute `i16::MAX + 1_i16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2b.rs:24:6
+ |
+LL | i32::MAX + 1,
+ | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2b.rs:30:6
+ |
+LL | i64::MAX + 1,
+ | ^^^^^^^^^^^^ attempt to compute `i64::MAX + 1_i64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2b.rs:36:6
+ |
+LL | u8::MAX + 1,
+ | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2b.rs:41:6
+ |
+LL | u16::MAX + 1,
+ | ^^^^^^^^^^^^ attempt to compute `u16::MAX + 1_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2b.rs:46:6
+ |
+LL | u32::MAX + 1,
+ | ^^^^^^^^^^^^ attempt to compute `u32::MAX + 1_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2b.rs:52:6
+ |
+LL | u64::MAX + 1,
+ | ^^^^^^^^^^^^ attempt to compute `u64::MAX + 1_u64`, which would overflow
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const-eval-overflow2c.rs b/tests/ui/consts/const-eval/const-eval-overflow2c.rs
new file mode 100644
index 000000000..33b892601
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow2c.rs
@@ -0,0 +1,69 @@
+#![allow(unused_imports)]
+
+// Note: the relevant lint pass here runs before some of the constant
+// evaluation below (e.g., that performed by codegen and llvm), so if you
+// change this warn to a deny, then the compiler will exit before
+// those errors are detected.
+
+use std::fmt;
+
+const VALS_I8: (i8,) =
+ (
+ i8::MIN * 2,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_I16: (i16,) =
+ (
+ i16::MIN * 2,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_I32: (i32,) =
+ (
+ i32::MIN * 2,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_I64: (i64,) =
+ (
+ i64::MIN * 2,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U8: (u8,) =
+ (
+ u8::MAX * 2,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U16: (u16,) = (
+ u16::MAX * 2,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U32: (u32,) = (
+ u32::MAX * 2,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+const VALS_U64: (u64,) =
+ (
+ u64::MAX * 2,
+ );
+ //~^^ ERROR evaluation of constant value failed
+
+fn main() {
+ foo(VALS_I8);
+ foo(VALS_I16);
+ foo(VALS_I32);
+ foo(VALS_I64);
+
+ foo(VALS_U8);
+ foo(VALS_U16);
+ foo(VALS_U32);
+ foo(VALS_U64);
+}
+
+fn foo<T>(_: T) {
+}
diff --git a/tests/ui/consts/const-eval/const-eval-overflow2c.stderr b/tests/ui/consts/const-eval/const-eval-overflow2c.stderr
new file mode 100644
index 000000000..1fad15492
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-overflow2c.stderr
@@ -0,0 +1,51 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2c.rs:12:6
+ |
+LL | i8::MIN * 2,
+ | ^^^^^^^^^^^ attempt to compute `i8::MIN * 2_i8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2c.rs:18:6
+ |
+LL | i16::MIN * 2,
+ | ^^^^^^^^^^^^ attempt to compute `i16::MIN * 2_i16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2c.rs:24:6
+ |
+LL | i32::MIN * 2,
+ | ^^^^^^^^^^^^ attempt to compute `i32::MIN * 2_i32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2c.rs:30:6
+ |
+LL | i64::MIN * 2,
+ | ^^^^^^^^^^^^ attempt to compute `i64::MIN * 2_i64`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2c.rs:36:6
+ |
+LL | u8::MAX * 2,
+ | ^^^^^^^^^^^ attempt to compute `u8::MAX * 2_u8`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2c.rs:41:6
+ |
+LL | u16::MAX * 2,
+ | ^^^^^^^^^^^^ attempt to compute `u16::MAX * 2_u16`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2c.rs:46:6
+ |
+LL | u32::MAX * 2,
+ | ^^^^^^^^^^^^ attempt to compute `u32::MAX * 2_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-overflow2c.rs:52:6
+ |
+LL | u64::MAX * 2,
+ | ^^^^^^^^^^^^ attempt to compute `u64::MAX * 2_u64`, which would overflow
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.rs b/tests/ui/consts/const-eval/const-eval-query-stack.rs
new file mode 100644
index 000000000..8f8a8cee3
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-query-stack.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Ztreat-err-as-bug=1
+// failure-status: 101
+// rustc-env:RUST_BACKTRACE=1
+// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> ""
+// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
+// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
+// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
+// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
+// normalize-stderr-test "thread.*panicked.*\n" -> ""
+// normalize-stderr-test "stack backtrace:\n" -> ""
+// normalize-stderr-test "\s\d{1,}: .*\n" -> ""
+// normalize-stderr-test "\s at .*\n" -> ""
+// normalize-stderr-test ".*note: Some details.*\n" -> ""
+
+#![allow(unconditional_panic)]
+
+const X: i32 = 1 / 0; //~ERROR constant
+
+fn main() {
+ let x: &'static i32 = &X;
+ println!("x={}", x);
+}
diff --git a/tests/ui/consts/const-eval/const-eval-query-stack.stderr b/tests/ui/consts/const-eval/const-eval-query-stack.stderr
new file mode 100644
index 000000000..b97975c4c
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-query-stack.stderr
@@ -0,0 +1,13 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-eval-query-stack.rs:17:16
+ |
+LL | const X: i32 = 1 / 0;
+ | ^^^^^ attempt to divide `1_i32` by zero
+
+query stack during panic:
+#0 [eval_to_allocation_raw] const-evaluating + checking `X`
+#1 [eval_to_const_value_raw] simplifying constant for the type system `X`
+#2 [eval_to_const_value_raw] simplifying constant for the type system `X`
+#3 [lint_mod] linting top-level module
+#4 [analysis] running analysis passes on this crate
+end of query stack
diff --git a/tests/ui/consts/const-eval/const-eval-span.rs b/tests/ui/consts/const-eval/const-eval-span.rs
new file mode 100644
index 000000000..82f101b47
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-span.rs
@@ -0,0 +1,14 @@
+// Check that error in constant evaluation of enum discriminant
+// provides the context for what caused the evaluation.
+
+struct S(i32);
+
+const CONSTANT: S = S(0);
+
+enum E {
+ V = CONSTANT,
+ //~^ ERROR mismatched types
+ //~| expected `isize`, found struct `S`
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/const-eval-span.stderr b/tests/ui/consts/const-eval/const-eval-span.stderr
new file mode 100644
index 000000000..c5b001899
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-eval-span.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+ --> $DIR/const-eval-span.rs:9:9
+ |
+LL | V = CONSTANT,
+ | ^^^^^^^^ expected `isize`, found struct `S`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
new file mode 100644
index 000000000..bf98d0394
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr
@@ -0,0 +1,258 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:26:49
+ |
+LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:29:43
+ |
+LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:32:45
+ |
+LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:35:45
+ |
+LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:38:45
+ |
+LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:41:47
+ |
+LL | const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:45:43
+ |
+LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:48:45
+ |
+LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:51:45
+ |
+LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:54:45
+ |
+LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:57:47
+ |
+LL | const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:61:45
+ |
+LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:64:45
+ |
+LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:67:47
+ |
+LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:70:47
+ |
+LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:73:39
+ |
+LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:76:41
+ |
+LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:79:41
+ |
+LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:82:41
+ |
+LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:85:43
+ |
+LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:88:39
+ |
+LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:91:41
+ |
+LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:94:41
+ |
+LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:97:41
+ |
+LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:100:43
+ |
+LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:103:41
+ |
+LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:106:41
+ |
+LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:109:43
+ |
+LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const-pointer-values-in-various-types.rs:112:43
+ |
+LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error: aborting due to 29 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const-pointer-values-in-various-types.rs b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.rs
new file mode 100644
index 000000000..45eed9d84
--- /dev/null
+++ b/tests/ui/consts/const-eval/const-pointer-values-in-various-types.rs
@@ -0,0 +1,114 @@
+// only-x86_64
+// stderr-per-bitwidth
+
+#[repr(C)]
+union Nonsense {
+ u: usize,
+ int_32_ref: &'static i32,
+ uint_8: u8,
+ uint_16: u16,
+ uint_32: u32,
+ uint_64: u64,
+ uint_128: u128,
+ int_8: i8,
+ int_16: i16,
+ int_32: i32,
+ int_64: i64,
+ int_128: i128,
+ float_32: f32,
+ float_64: f64,
+ truthy_falsey: bool,
+ character: char,
+ stringy: &'static str,
+}
+
+fn main() {
+ const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_U128_UNION: u128 = unsafe { Nonsense { int_32_ref: &3 }.uint_128 };
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
+
+ const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_I128_UNION: i128 = unsafe { Nonsense { int_32_ref: &3 }.int_128 };
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
+
+ const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey };
+ //~^ ERROR evaluation of constant value failed
+
+ const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey };
+ //~^ ERROR evaluation of constant value failed
+
+ const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character };
+ //~^ ERROR evaluation of constant value failed
+}
diff --git a/tests/ui/consts/const-eval/const_fn_ptr.rs b/tests/ui/consts/const-eval/const_fn_ptr.rs
new file mode 100644
index 000000000..b3c677c69
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_fn_ptr.rs
@@ -0,0 +1,36 @@
+// run-pass
+// compile-flags: -Zunleash-the-miri-inside-of-you
+
+fn double(x: usize) -> usize { x * 2 }
+const fn double_const(x: usize) -> usize { x * 2 }
+
+const X: fn(usize) -> usize = double;
+const X_CONST: fn(usize) -> usize = double_const;
+
+const fn bar(x: usize) -> usize {
+ X(x)
+}
+
+const fn bar_const(x: usize) -> usize {
+ X_CONST(x)
+}
+
+const fn foo(x: fn(usize) -> usize, y: usize) -> usize {
+ x(y)
+}
+
+fn main() {
+ const Y: usize = bar_const(2);
+ assert_eq!(Y, 4);
+ let y = bar_const(2);
+ assert_eq!(y, 4);
+ let y = bar(2);
+ assert_eq!(y, 4);
+
+ const Z: usize = foo(double_const, 2);
+ assert_eq!(Z, 4);
+ let z = foo(double_const, 2);
+ assert_eq!(z, 4);
+ let z = foo(double, 2);
+ assert_eq!(z, 4);
+}
diff --git a/tests/ui/consts/const-eval/const_fn_ptr.stderr b/tests/ui/consts/const-eval/const_fn_ptr.stderr
new file mode 100644
index 000000000..ca1585f88
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_fn_ptr.stderr
@@ -0,0 +1,20 @@
+warning: skipping const checks
+ |
+help: skipping check that does not even have a feature gate
+ --> $DIR/const_fn_ptr.rs:11:5
+ |
+LL | X(x)
+ | ^^^^
+help: skipping check that does not even have a feature gate
+ --> $DIR/const_fn_ptr.rs:15:5
+ |
+LL | X_CONST(x)
+ | ^^^^^^^^^^
+help: skipping check that does not even have a feature gate
+ --> $DIR/const_fn_ptr.rs:19:5
+ |
+LL | x(y)
+ | ^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/consts/const-eval/const_fn_ptr_fail.rs b/tests/ui/consts/const-eval/const_fn_ptr_fail.rs
new file mode 100644
index 000000000..1896eba82
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_fn_ptr_fail.rs
@@ -0,0 +1,12 @@
+// run-pass
+// compile-flags: -Zunleash-the-miri-inside-of-you
+#![allow(unused)]
+
+fn double(x: usize) -> usize { x * 2 }
+const X: fn(usize) -> usize = double;
+
+const fn bar(x: usize) -> usize {
+ X(x) // FIXME: this should error someday
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/const_fn_ptr_fail.stderr b/tests/ui/consts/const-eval/const_fn_ptr_fail.stderr
new file mode 100644
index 000000000..ec5de5759
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_fn_ptr_fail.stderr
@@ -0,0 +1,10 @@
+warning: skipping const checks
+ |
+help: skipping check that does not even have a feature gate
+ --> $DIR/const_fn_ptr_fail.rs:9:5
+ |
+LL | X(x) // FIXME: this should error someday
+ | ^^^^
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs b/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs
new file mode 100644
index 000000000..b873940c4
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_fn_ptr_fail2.rs
@@ -0,0 +1,20 @@
+// compile-flags: -Zunleash-the-miri-inside-of-you
+
+fn double(x: usize) -> usize {
+ x * 2
+}
+const X: fn(usize) -> usize = double;
+
+const fn bar(x: fn(usize) -> usize, y: usize) -> usize {
+ x(y)
+ //~^ ERROR evaluation of constant value failed
+ //~| ERROR evaluation of constant value failed
+}
+
+const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
+const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
+
+fn main() {
+ assert_eq!(Y, 4);
+ assert_eq!(Z, 4);
+}
diff --git a/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr
new file mode 100644
index 000000000..0734f479f
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_fn_ptr_fail2.stderr
@@ -0,0 +1,45 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_fn_ptr_fail2.rs:9:5
+ |
+LL | x(y)
+ | ^^^^ calling non-const function `double`
+ |
+note: inside `bar`
+ --> $DIR/const_fn_ptr_fail2.rs:9:5
+ |
+LL | x(y)
+ | ^^^^
+note: inside `Y`
+ --> $DIR/const_fn_ptr_fail2.rs:14:18
+ |
+LL | const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday
+ | ^^^^^^^^^
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_fn_ptr_fail2.rs:9:5
+ |
+LL | x(y)
+ | ^^^^ calling non-const function `double`
+ |
+note: inside `bar`
+ --> $DIR/const_fn_ptr_fail2.rs:9:5
+ |
+LL | x(y)
+ | ^^^^
+note: inside `Z`
+ --> $DIR/const_fn_ptr_fail2.rs:15:18
+ |
+LL | const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday
+ | ^^^^^^^^^^^^^^
+
+warning: skipping const checks
+ |
+help: skipping check that does not even have a feature gate
+ --> $DIR/const_fn_ptr_fail2.rs:9:5
+ |
+LL | x(y)
+ | ^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const_let.rs b/tests/ui/consts/const-eval/const_let.rs
new file mode 100644
index 000000000..1e2bcc55b
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_let.rs
@@ -0,0 +1,29 @@
+fn main() {}
+
+struct FakeNeedsDrop;
+
+impl Drop for FakeNeedsDrop {
+ fn drop(&mut self) {}
+}
+
+// ok
+const X: FakeNeedsDrop = { let x = FakeNeedsDrop; x };
+
+// ok (used to incorrectly error, see #62273)
+const X2: FakeNeedsDrop = { let x; x = FakeNeedsDrop; x };
+
+// error
+const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x };
+//~^ ERROR destructor of
+
+// error
+const Y2: FakeNeedsDrop = { let mut x; x = FakeNeedsDrop; x = FakeNeedsDrop; x };
+//~^ ERROR destructor of
+
+// error
+const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); };
+//~^ ERROR destructor of
+
+// error
+const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); };
+//~^ ERROR destructor of
diff --git a/tests/ui/consts/const-eval/const_let.stderr b/tests/ui/consts/const-eval/const_let.stderr
new file mode 100644
index 000000000..63442f557
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_let.stderr
@@ -0,0 +1,35 @@
+error[E0493]: destructor of `FakeNeedsDrop` cannot be evaluated at compile-time
+ --> $DIR/const_let.rs:16:32
+ |
+LL | const Y: FakeNeedsDrop = { let mut x = FakeNeedsDrop; x = FakeNeedsDrop; x };
+ | ^^^^^ - value is dropped here
+ | |
+ | the destructor for this type cannot be evaluated in constants
+
+error[E0493]: destructor of `FakeNeedsDrop` cannot be evaluated at compile-time
+ --> $DIR/const_let.rs:20:33
+ |
+LL | const Y2: FakeNeedsDrop = { let mut x; x = FakeNeedsDrop; x = FakeNeedsDrop; x };
+ | ^^^^^ - value is dropped here
+ | |
+ | the destructor for this type cannot be evaluated in constants
+
+error[E0493]: destructor of `Option<FakeNeedsDrop>` cannot be evaluated at compile-time
+ --> $DIR/const_let.rs:24:21
+ |
+LL | const Z: () = { let mut x = None; x = Some(FakeNeedsDrop); };
+ | ^^^^^ - value is dropped here
+ | |
+ | the destructor for this type cannot be evaluated in constants
+
+error[E0493]: destructor of `Option<FakeNeedsDrop>` cannot be evaluated at compile-time
+ --> $DIR/const_let.rs:28:22
+ |
+LL | const Z2: () = { let mut x; x = None; x = Some(FakeNeedsDrop); };
+ | ^^^^^ - value is dropped here
+ | |
+ | the destructor for this type cannot be evaluated in constants
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/const-eval/const_panic.rs b/tests/ui/consts/const-eval/const_panic.rs
new file mode 100644
index 000000000..5b9a8f8e2
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic.rs
@@ -0,0 +1,40 @@
+#![allow(non_fmt_panics)]
+#![crate_type = "lib"]
+
+const MSG: &str = "hello";
+
+const Z: () = std::panic!("cheese");
+//~^ ERROR evaluation of constant value failed
+
+const Z2: () = std::panic!();
+//~^ ERROR evaluation of constant value failed
+
+const Y: () = std::unreachable!();
+//~^ ERROR evaluation of constant value failed
+
+const X: () = std::unimplemented!();
+//~^ ERROR evaluation of constant value failed
+
+const W: () = std::panic!(MSG);
+//~^ ERROR evaluation of constant value failed
+
+const W2: () = std::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
+
+const Z_CORE: () = core::panic!("cheese");
+//~^ ERROR evaluation of constant value failed
+
+const Z2_CORE: () = core::panic!();
+//~^ ERROR evaluation of constant value failed
+
+const Y_CORE: () = core::unreachable!();
+//~^ ERROR evaluation of constant value failed
+
+const X_CORE: () = core::unimplemented!();
+//~^ ERROR evaluation of constant value failed
+
+const W_CORE: () = core::panic!(MSG);
+//~^ ERROR evaluation of constant value failed
+
+const W2_CORE: () = core::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
diff --git a/tests/ui/consts/const-eval/const_panic.stderr b/tests/ui/consts/const-eval/const_panic.stderr
new file mode 100644
index 000000000..0f7be4607
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic.stderr
@@ -0,0 +1,99 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:6:15
+ |
+LL | const Z: () = std::panic!("cheese");
+ | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:6:15
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:9:16
+ |
+LL | const Z2: () = std::panic!();
+ | ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:9:16
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:12:15
+ |
+LL | const Y: () = std::unreachable!();
+ | ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:12:15
+ |
+ = note: this error originates in the macro `$crate::panic::unreachable_2015` which comes from the expansion of the macro `std::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:15:15
+ |
+LL | const X: () = std::unimplemented!();
+ | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:15:15
+ |
+ = note: this error originates in the macro `std::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:18:15
+ |
+LL | const W: () = std::panic!(MSG);
+ | ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:18:15
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:21:16
+ |
+LL | const W2: () = std::panic!("{}", MSG);
+ | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:21:16
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:24:20
+ |
+LL | const Z_CORE: () = core::panic!("cheese");
+ | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic.rs:24:20
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:27:21
+ |
+LL | const Z2_CORE: () = core::panic!();
+ | ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:27:21
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:30:20
+ |
+LL | const Y_CORE: () = core::unreachable!();
+ | ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:30:20
+ |
+ = note: this error originates in the macro `$crate::panic::unreachable_2015` which comes from the expansion of the macro `core::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:33:20
+ |
+LL | const X_CORE: () = core::unimplemented!();
+ | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:33:20
+ |
+ = note: this error originates in the macro `core::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:36:20
+ |
+LL | const W_CORE: () = core::panic!(MSG);
+ | ^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:36:20
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic.rs:39:21
+ |
+LL | const W2_CORE: () = core::panic!("{}", MSG);
+ | ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic.rs:39:21
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 12 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const_panic_2021.rs b/tests/ui/consts/const-eval/const_panic_2021.rs
new file mode 100644
index 000000000..4702aa2f5
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic_2021.rs
@@ -0,0 +1,34 @@
+// edition:2021
+#![crate_type = "lib"]
+
+const MSG: &str = "hello";
+
+const A: () = std::panic!("blåhaj");
+//~^ ERROR evaluation of constant value failed
+
+const B: () = std::panic!();
+//~^ ERROR evaluation of constant value failed
+
+const C: () = std::unreachable!();
+//~^ ERROR evaluation of constant value failed
+
+const D: () = std::unimplemented!();
+//~^ ERROR evaluation of constant value failed
+
+const E: () = std::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
+
+const A_CORE: () = core::panic!("shark");
+//~^ ERROR evaluation of constant value failed
+
+const B_CORE: () = core::panic!();
+//~^ ERROR evaluation of constant value failed
+
+const C_CORE: () = core::unreachable!();
+//~^ ERROR evaluation of constant value failed
+
+const D_CORE: () = core::unimplemented!();
+//~^ ERROR evaluation of constant value failed
+
+const E_CORE: () = core::panic!("{}", MSG);
+//~^ ERROR evaluation of constant value failed
diff --git a/tests/ui/consts/const-eval/const_panic_2021.stderr b/tests/ui/consts/const-eval/const_panic_2021.stderr
new file mode 100644
index 000000000..192fa3a12
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic_2021.stderr
@@ -0,0 +1,83 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:6:15
+ |
+LL | const A: () = std::panic!("blåhaj");
+ | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'blåhaj', $DIR/const_panic_2021.rs:6:15
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:9:15
+ |
+LL | const B: () = std::panic!();
+ | ^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:9:15
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:12:15
+ |
+LL | const C: () = std::unreachable!();
+ | ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:12:15
+ |
+ = note: this error originates in the macro `$crate::panic::unreachable_2021` which comes from the expansion of the macro `std::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:15:15
+ |
+LL | const D: () = std::unimplemented!();
+ | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:15:15
+ |
+ = note: this error originates in the macro `std::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:18:15
+ |
+LL | const E: () = std::panic!("{}", MSG);
+ | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:18:15
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `std::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:21:20
+ |
+LL | const A_CORE: () = core::panic!("shark");
+ | ^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'shark', $DIR/const_panic_2021.rs:21:20
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:24:20
+ |
+LL | const B_CORE: () = core::panic!();
+ | ^^^^^^^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/const_panic_2021.rs:24:20
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:27:20
+ |
+LL | const C_CORE: () = core::unreachable!();
+ | ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:27:20
+ |
+ = note: this error originates in the macro `$crate::panic::unreachable_2021` which comes from the expansion of the macro `core::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:30:20
+ |
+LL | const D_CORE: () = core::unimplemented!();
+ | ^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_2021.rs:30:20
+ |
+ = note: this error originates in the macro `core::unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_2021.rs:33:20
+ |
+LL | const E_CORE: () = core::panic!("{}", MSG);
+ | ^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'hello', $DIR/const_panic_2021.rs:33:20
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2021` which comes from the expansion of the macro `core::panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 10 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const_panic_libcore_bin.rs b/tests/ui/consts/const-eval/const_panic_libcore_bin.rs
new file mode 100644
index 000000000..d4dc1a51d
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic_libcore_bin.rs
@@ -0,0 +1,25 @@
+#![crate_type = "bin"]
+#![feature(lang_items)]
+#![no_main]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+const Z: () = panic!("cheese");
+//~^ ERROR evaluation of constant value failed
+
+const Y: () = unreachable!();
+//~^ ERROR evaluation of constant value failed
+
+const X: () = unimplemented!();
+//~^ ERROR evaluation of constant value failed
+
+#[lang = "eh_personality"]
+fn eh() {}
+#[lang = "eh_catch_typeinfo"]
+static EH_CATCH_TYPEINFO: u8 = 0;
+
+#[panic_handler]
+fn panic(_info: &PanicInfo) -> ! {
+ loop {}
+}
diff --git a/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr b/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr
new file mode 100644
index 000000000..df19ed4a8
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic_libcore_bin.stderr
@@ -0,0 +1,27 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_libcore_bin.rs:8:15
+ |
+LL | const Z: () = panic!("cheese");
+ | ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'cheese', $DIR/const_panic_libcore_bin.rs:8:15
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_libcore_bin.rs:11:15
+ |
+LL | const Y: () = unreachable!();
+ | ^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_bin.rs:11:15
+ |
+ = note: this error originates in the macro `$crate::panic::unreachable_2015` which comes from the expansion of the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_libcore_bin.rs:14:15
+ |
+LL | const X: () = unimplemented!();
+ | ^^^^^^^^^^^^^^^^ the evaluated program panicked at 'not implemented', $DIR/const_panic_libcore_bin.rs:14:15
+ |
+ = note: this error originates in the macro `unimplemented` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr
new file mode 100644
index 000000000..3553a18d3
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic_stability.e2018.stderr
@@ -0,0 +1,16 @@
+warning: panic message is not a string literal
+ --> $DIR/const_panic_stability.rs:14:12
+ |
+LL | panic!({ "foo" });
+ | ^^^^^^^^^
+ |
+ = note: this usage of `panic!()` is deprecated; it will be a hard error in Rust 2021
+ = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>
+ = note: `#[warn(non_fmt_panics)]` on by default
+help: add a "{}" format string to `Display` the message
+ |
+LL | panic!("{}", { "foo" });
+ | +++++
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/consts/const-eval/const_panic_stability.e2021.stderr b/tests/ui/consts/const-eval/const_panic_stability.e2021.stderr
new file mode 100644
index 000000000..9e8179181
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic_stability.e2021.stderr
@@ -0,0 +1,13 @@
+error: format argument must be a string literal
+ --> $DIR/const_panic_stability.rs:14:12
+ |
+LL | panic!({ "foo" });
+ | ^^^^^^^^^
+ |
+help: you might be missing a string literal to format with
+ |
+LL | panic!("{}", { "foo" });
+ | +++++
+
+error: aborting due to previous error
+
diff --git a/tests/ui/consts/const-eval/const_panic_stability.rs b/tests/ui/consts/const-eval/const_panic_stability.rs
new file mode 100644
index 000000000..1aee6f27e
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic_stability.rs
@@ -0,0 +1,17 @@
+// revisions: e2018 e2021
+//[e2018] edition:2018
+//[e2021] edition:2021
+//[e2018] check-pass
+#![crate_type = "lib"]
+#![stable(feature = "foo", since = "1.0.0")]
+#![feature(staged_api)]
+
+#[stable(feature = "foo", since = "1.0.0")]
+#[rustc_const_stable(feature = "foo", since = "1.0.0")]
+const fn foo() {
+ assert!(false);
+ assert!(false, "foo");
+ panic!({ "foo" });
+ //[e2018]~^ WARNING panic message is not a string literal
+ //[e2021]~^^ ERROR format argument must be a string literal
+}
diff --git a/tests/ui/consts/const-eval/const_panic_track_caller.rs b/tests/ui/consts/const-eval/const_panic_track_caller.rs
new file mode 100644
index 000000000..9cf7a3ba7
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic_track_caller.rs
@@ -0,0 +1,22 @@
+#![allow(non_fmt_panics)]
+#![crate_type = "lib"]
+
+#[track_caller]
+const fn a() -> u32 {
+ panic!("hey")
+}
+
+#[track_caller]
+const fn b() -> u32 {
+ a()
+}
+
+const fn c() -> u32 {
+ b()
+ //~^ ERROR evaluation of constant value failed
+ //~| NOTE the evaluated program panicked
+ //~| NOTE inside
+}
+
+const X: u32 = c();
+//~^ NOTE inside
diff --git a/tests/ui/consts/const-eval/const_panic_track_caller.stderr b/tests/ui/consts/const-eval/const_panic_track_caller.stderr
new file mode 100644
index 000000000..846458176
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_panic_track_caller.stderr
@@ -0,0 +1,20 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_panic_track_caller.rs:15:5
+ |
+LL | b()
+ | ^^^ the evaluated program panicked at 'hey', $DIR/const_panic_track_caller.rs:15:5
+ |
+note: inside `c`
+ --> $DIR/const_panic_track_caller.rs:15:5
+ |
+LL | b()
+ | ^^^
+note: inside `X`
+ --> $DIR/const_panic_track_caller.rs:21:16
+ |
+LL | const X: u32 = c();
+ | ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const_prop_errors.rs b/tests/ui/consts/const-eval/const_prop_errors.rs
new file mode 100644
index 000000000..f9a36d379
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_prop_errors.rs
@@ -0,0 +1,14 @@
+// check-pass
+
+pub trait Foo {
+ fn foo(self) -> u32;
+}
+
+impl<T> Foo for T {
+ fn foo(self) -> u32 {
+ fn bar<T>() { loop {} }
+ bar::<T> as u32
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops.rs b/tests/ui/consts/const-eval/const_raw_ptr_ops.rs
new file mode 100644
index 000000000..cd7c98007
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_raw_ptr_ops.rs
@@ -0,0 +1,6 @@
+fn main() {}
+
+// unconst and bad, will thus error in miri
+const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR can't compare
+// unconst and bad, will thus error in miri
+const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR can't compare
diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr b/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr
new file mode 100644
index 000000000..12244450e
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_raw_ptr_ops.stderr
@@ -0,0 +1,29 @@
+error[E0277]: can't compare `*const i32` with `_` in const contexts
+ --> $DIR/const_raw_ptr_ops.rs:4:43
+ |
+LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 };
+ | ^^ no implementation for `*const i32 == _`
+ |
+ = help: the trait `~const PartialEq<_>` is not implemented for `*const i32`
+note: the trait `PartialEq<_>` is implemented for `*const i32`, but that implementation is not `const`
+ --> $DIR/const_raw_ptr_ops.rs:4:43
+ |
+LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 };
+ | ^^
+
+error[E0277]: can't compare `*const i32` with `_` in const contexts
+ --> $DIR/const_raw_ptr_ops.rs:6:44
+ |
+LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 };
+ | ^^ no implementation for `*const i32 == _`
+ |
+ = help: the trait `~const PartialEq<_>` is not implemented for `*const i32`
+note: the trait `PartialEq<_>` is implemented for `*const i32`, but that implementation is not `const`
+ --> $DIR/const_raw_ptr_ops.rs:6:44
+ |
+LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 };
+ | ^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops2.rs b/tests/ui/consts/const-eval/const_raw_ptr_ops2.rs
new file mode 100644
index 000000000..ec5508a1e
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_raw_ptr_ops2.rs
@@ -0,0 +1,10 @@
+fn main() {}
+
+// fine
+const Z: i32 = unsafe { *(&1 as *const i32) };
+
+// bad, will thus error in miri
+const Z2: i32 = unsafe { *(42 as *const i32) }; //~ ERROR evaluation of constant value failed
+//~| is a dangling pointer
+const Z3: i32 = unsafe { *(44 as *const i32) }; //~ ERROR evaluation of constant value failed
+//~| is a dangling pointer
diff --git a/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr b/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr
new file mode 100644
index 000000000..e41dea873
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_raw_ptr_ops2.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_raw_ptr_ops2.rs:7:26
+ |
+LL | const Z2: i32 = unsafe { *(42 as *const i32) };
+ | ^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2a[noalloc] is a dangling pointer (it has no provenance)
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/const_raw_ptr_ops2.rs:9:26
+ |
+LL | const Z3: i32 = unsafe { *(44 as *const i32) };
+ | ^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: 0x2c[noalloc] is a dangling pointer (it has no provenance)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/const_signed_pat.rs b/tests/ui/consts/const-eval/const_signed_pat.rs
new file mode 100644
index 000000000..c61239bb6
--- /dev/null
+++ b/tests/ui/consts/const-eval/const_signed_pat.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+fn main() {
+ const MIN: i8 = -5;
+ match 5i8 {
+ MIN..=-1 => {},
+ _ => {},
+ }
+}
diff --git a/tests/ui/consts/const-eval/dangling.rs b/tests/ui/consts/const-eval/dangling.rs
new file mode 100644
index 000000000..4fcf87921
--- /dev/null
+++ b/tests/ui/consts/const-eval/dangling.rs
@@ -0,0 +1,10 @@
+use std::mem;
+
+// Make sure we error with the right kind of error on a too large slice.
+const TEST: () = { unsafe {
+ let slice: *const [u8] = mem::transmute((1usize, usize::MAX));
+ let _val = &*slice; //~ ERROR: evaluation of constant value failed
+ //~| slice is bigger than largest supported object
+} };
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/dangling.stderr b/tests/ui/consts/const-eval/dangling.stderr
new file mode 100644
index 000000000..92d70573d
--- /dev/null
+++ b/tests/ui/consts/const-eval/dangling.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/dangling.rs:6:16
+ |
+LL | let _val = &*slice;
+ | ^^^^^^^ invalid metadata in wide pointer: slice is bigger than largest supported object
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/dont_promote_unstable_const_fn.rs b/tests/ui/consts/const-eval/dont_promote_unstable_const_fn.rs
new file mode 100644
index 000000000..4b3cf7073
--- /dev/null
+++ b/tests/ui/consts/const-eval/dont_promote_unstable_const_fn.rs
@@ -0,0 +1,24 @@
+#![unstable(feature = "humans",
+ reason = "who ever let humans program computers,
+ we're apparently really bad at it",
+ issue = "none")]
+
+#![feature(staged_api)]
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[rustc_const_unstable(feature="foo", issue = "none")]
+const fn foo() -> u32 { 42 }
+
+fn meh() -> u32 { 42 }
+
+const fn bar() -> u32 { foo() } //~ ERROR `foo` is not yet stable as a const fn
+
+fn a() {
+ let _: &'static u32 = &foo(); //~ ERROR temporary value dropped while borrowed
+}
+
+fn main() {
+ let _: &'static u32 = &meh(); //~ ERROR temporary value dropped while borrowed
+ let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis();
+ //~^ ERROR temporary value dropped while borrowed
+}
diff --git a/tests/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr b/tests/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr
new file mode 100644
index 000000000..2e697b219
--- /dev/null
+++ b/tests/ui/consts/const-eval/dont_promote_unstable_const_fn.stderr
@@ -0,0 +1,43 @@
+error: `foo` is not yet stable as a const fn
+ --> $DIR/dont_promote_unstable_const_fn.rs:14:25
+ |
+LL | const fn bar() -> u32 { foo() }
+ | ^^^^^
+ |
+ = help: add `#![feature(foo)]` to the crate attributes to enable
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/dont_promote_unstable_const_fn.rs:17:28
+ |
+LL | let _: &'static u32 = &foo();
+ | ------------ ^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/dont_promote_unstable_const_fn.rs:21:28
+ |
+LL | let _: &'static u32 = &meh();
+ | ------------ ^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/dont_promote_unstable_const_fn.rs:22:26
+ |
+LL | let x: &'static _ = &std::time::Duration::from_millis(42).subsec_millis();
+ | ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL |
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs b/tests/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs
new file mode 100644
index 000000000..ea35f4680
--- /dev/null
+++ b/tests/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.rs
@@ -0,0 +1,10 @@
+// aux-build:stability.rs
+
+extern crate stability;
+
+use stability::foo;
+
+fn main() {
+ let _: &'static u32 = &foo(); //~ ERROR temporary value dropped while borrowed
+ let _x: &'static u32 = &foo(); //~ ERROR temporary value dropped while borrowed
+}
diff --git a/tests/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr b/tests/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr
new file mode 100644
index 000000000..aa742d784
--- /dev/null
+++ b/tests/ui/consts/const-eval/dont_promote_unstable_const_fn_cross_crate.stderr
@@ -0,0 +1,24 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/dont_promote_unstable_const_fn_cross_crate.rs:8:28
+ |
+LL | let _: &'static u32 = &foo();
+ | ------------ ^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL | let _x: &'static u32 = &foo();
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/dont_promote_unstable_const_fn_cross_crate.rs:9:29
+ |
+LL | let _x: &'static u32 = &foo();
+ | ------------ ^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/const-eval/double_check.rs b/tests/ui/consts/const-eval/double_check.rs
new file mode 100644
index 000000000..56ca0aa1f
--- /dev/null
+++ b/tests/ui/consts/const-eval/double_check.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+enum Foo {
+ A = 5,
+ B = 42,
+}
+enum Bar {
+ C = 42,
+ D = 99,
+}
+#[repr(C)]
+union Union {
+ foo: &'static Foo,
+ bar: &'static Bar,
+ u8: &'static u8,
+}
+static BAR: u8 = 42;
+static FOO: (&Foo, &Bar) = unsafe {(
+ Union { u8: &BAR }.foo,
+ Union { u8: &BAR }.bar,
+)};
+
+static FOO2: (&Foo, &Bar) = unsafe {(std::mem::transmute(&BAR), std::mem::transmute(&BAR))};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/double_check2.rs b/tests/ui/consts/const-eval/double_check2.rs
new file mode 100644
index 000000000..81f5dde45
--- /dev/null
+++ b/tests/ui/consts/const-eval/double_check2.rs
@@ -0,0 +1,32 @@
+// check-pass
+
+// This test exhibits undefined behavior, but it is very expensive and complex to check for such
+// UB in constants.
+// Thus, we do not detect it if you create references to statics in ways that are UB.
+
+enum Foo {
+ A = 5,
+ B = 42,
+}
+enum Bar {
+ C = 42,
+ D = 99,
+}
+#[repr(C)]
+union Union {
+ foo: &'static Foo,
+ bar: &'static Bar,
+ u8: &'static u8,
+}
+static BAR: u8 = 5;
+static FOO: (&Foo, &Bar) = unsafe {
+ (
+ // undefined behavior
+ Union { u8: &BAR }.foo,
+ Union { u8: &BAR }.bar,
+ )
+};
+static FOO2: (&Foo, &Bar) = unsafe { (std::mem::transmute(&BAR), std::mem::transmute(&BAR)) };
+//^ undefined behavior
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/duration_conversion.rs b/tests/ui/consts/const-eval/duration_conversion.rs
new file mode 100644
index 000000000..87b12937d
--- /dev/null
+++ b/tests/ui/consts/const-eval/duration_conversion.rs
@@ -0,0 +1,16 @@
+// check-pass
+
+use std::time::Duration;
+
+fn main() {
+ const _ONE_SECOND: Duration = Duration::from_nanos(1_000_000_000);
+ const _ONE_MILLISECOND: Duration = Duration::from_nanos(1_000_000);
+ const _ONE_MICROSECOND: Duration = Duration::from_nanos(1_000);
+ const _ONE_NANOSECOND: Duration = Duration::from_nanos(1);
+ const _ONE: usize = _ONE_SECOND.as_secs() as usize;
+ const _TWO: usize = _ONE_MILLISECOND.subsec_millis() as usize;
+ const _THREE: usize = _ONE_MICROSECOND.subsec_micros() as usize;
+ const _FOUR: usize = _ONE_NANOSECOND.subsec_nanos() as usize;
+ const _0: [[u8; _ONE]; _TWO] = [[1; _ONE]; _TWO];
+ const _1: [[u8; _THREE]; _FOUR] = [[3; _THREE]; _FOUR];
+}
diff --git a/tests/ui/consts/const-eval/enum_discr.rs b/tests/ui/consts/const-eval/enum_discr.rs
new file mode 100644
index 000000000..e09258f11
--- /dev/null
+++ b/tests/ui/consts/const-eval/enum_discr.rs
@@ -0,0 +1,25 @@
+// run-pass
+
+enum Foo {
+ X = 42,
+ Y = Foo::X as isize - 3,
+}
+
+enum Bar {
+ X,
+ Y = Bar::X as isize + 2,
+}
+
+enum Boo {
+ X = Boo::Y as isize * 2,
+ Y = 9,
+}
+
+fn main() {
+ assert_eq!(Foo::X as isize, 42);
+ assert_eq!(Foo::Y as isize, 39);
+ assert_eq!(Bar::X as isize, 0);
+ assert_eq!(Bar::Y as isize, 2);
+ assert_eq!(Boo::X as isize, 18);
+ assert_eq!(Boo::Y as isize, 9);
+}
diff --git a/tests/ui/consts/const-eval/erroneous-const.rs b/tests/ui/consts/const-eval/erroneous-const.rs
new file mode 100644
index 000000000..e0fd057a2
--- /dev/null
+++ b/tests/ui/consts/const-eval/erroneous-const.rs
@@ -0,0 +1,21 @@
+//! Make sure we error on erroneous consts even if they are unused.
+#![allow(unconditional_panic)]
+
+struct PrintName<T>(T);
+impl<T> PrintName<T> {
+ const VOID: () = [()][2]; //~ERROR evaluation of `PrintName::<i32>::VOID` failed
+}
+
+const fn no_codegen<T>() {
+ if false {
+ // This bad constant is only used in dead code in a no-codegen function... and yet we still
+ // must make sure that the build fails.
+ let _ = PrintName::<T>::VOID; //~ constant
+ }
+}
+
+pub static FOO: () = no_codegen::<i32>();
+
+fn main() {
+ FOO
+}
diff --git a/tests/ui/consts/const-eval/erroneous-const.stderr b/tests/ui/consts/const-eval/erroneous-const.stderr
new file mode 100644
index 000000000..03030392a
--- /dev/null
+++ b/tests/ui/consts/const-eval/erroneous-const.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of `PrintName::<i32>::VOID` failed
+ --> $DIR/erroneous-const.rs:6:22
+ |
+LL | const VOID: () = [()][2];
+ | ^^^^^^^ index out of bounds: the length is 1 but the index is 2
+
+note: erroneous constant used
+ --> $DIR/erroneous-const.rs:13:17
+ |
+LL | let _ = PrintName::<T>::VOID;
+ | ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/erroneous-const2.rs b/tests/ui/consts/const-eval/erroneous-const2.rs
new file mode 100644
index 000000000..15c0f9107
--- /dev/null
+++ b/tests/ui/consts/const-eval/erroneous-const2.rs
@@ -0,0 +1,19 @@
+//! Make sure we error on erroneous consts even if they are unused.
+#![allow(unconditional_panic)]
+
+struct PrintName<T>(T);
+impl<T> PrintName<T> {
+ const VOID: () = [()][2]; //~ERROR evaluation of `PrintName::<i32>::VOID` failed
+}
+
+pub static FOO: () = {
+ if false {
+ // This bad constant is only used in dead code in a static initializer... and yet we still
+ // must make sure that the build fails.
+ let _ = PrintName::<i32>::VOID; //~ constant
+ }
+};
+
+fn main() {
+ FOO
+}
diff --git a/tests/ui/consts/const-eval/erroneous-const2.stderr b/tests/ui/consts/const-eval/erroneous-const2.stderr
new file mode 100644
index 000000000..8626f4d78
--- /dev/null
+++ b/tests/ui/consts/const-eval/erroneous-const2.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of `PrintName::<i32>::VOID` failed
+ --> $DIR/erroneous-const2.rs:6:22
+ |
+LL | const VOID: () = [()][2];
+ | ^^^^^^^ index out of bounds: the length is 1 but the index is 2
+
+note: erroneous constant used
+ --> $DIR/erroneous-const2.rs:13:17
+ |
+LL | let _ = PrintName::<i32>::VOID;
+ | ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/extern_fat_pointer.rs b/tests/ui/consts/const-eval/extern_fat_pointer.rs
new file mode 100644
index 000000000..d91d07827
--- /dev/null
+++ b/tests/ui/consts/const-eval/extern_fat_pointer.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+#![feature(extern_types)]
+
+extern "C" {
+ type Opaque;
+}
+
+const FOO: *const u8 = &42 as *const _ as *const Opaque as *const u8;
+
+fn main() {
+ let _foo = FOO;
+}
diff --git a/tests/ui/consts/const-eval/format.rs b/tests/ui/consts/const-eval/format.rs
new file mode 100644
index 000000000..0d8b7c12d
--- /dev/null
+++ b/tests/ui/consts/const-eval/format.rs
@@ -0,0 +1,13 @@
+const fn failure() {
+ panic!("{:?}", 0);
+ //~^ ERROR cannot call non-const formatting macro in constant functions
+}
+
+const fn print() {
+ println!("{:?}", 0);
+ //~^ ERROR cannot call non-const formatting macro in constant functions
+ //~| ERROR `Arguments::<'a>::new_v1` is not yet stable as a const fn
+ //~| ERROR cannot call non-const fn `_print` in constant functions
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/format.stderr b/tests/ui/consts/const-eval/format.stderr
new file mode 100644
index 000000000..4bf39db58
--- /dev/null
+++ b/tests/ui/consts/const-eval/format.stderr
@@ -0,0 +1,95 @@
+error[E0015]: cannot call non-const formatting macro in constant functions
+ --> $DIR/format.rs:2:20
+ |
+LL | panic!("{:?}", 0);
+ | ^
+ |
+ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+ = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0015]: cannot call non-const formatting macro in constant functions
+ --> $DIR/format.rs:7:22
+ |
+LL | println!("{:?}", 0);
+ | ^
+ |
+ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+ = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: `Arguments::<'a>::new_v1` is not yet stable as a const fn
+ --> $DIR/format.rs:7:5
+ |
+LL | println!("{:?}", 0);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = help: add `#![feature(const_fmt_arguments_new)]` to the crate attributes to enable
+ = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0015]: cannot call non-const fn `_print` in constant functions
+ --> $DIR/format.rs:7:5
+ |
+LL | println!("{:?}", 0);
+ | ^^^^^^^^^^^^^^^^^^^
+ |
+ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+ = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/format.rs:2:12
+ |
+LL | panic!("{:?}", 0);
+ | ^^^^^^
+
+note: erroneous constant used
+ --> $DIR/format.rs:2:12
+ |
+LL | panic!("{:?}", 0);
+ | ^^^^^^
+
+note: erroneous constant used
+ --> $DIR/format.rs:2:20
+ |
+LL | panic!("{:?}", 0);
+ | ^
+ |
+ = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/format.rs:2:20
+ |
+LL | panic!("{:?}", 0);
+ | ^
+ |
+ = note: this note originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/format.rs:7:14
+ |
+LL | println!("{:?}", 0);
+ | ^^^^^^
+
+note: erroneous constant used
+ --> $DIR/format.rs:7:14
+ |
+LL | println!("{:?}", 0);
+ | ^^^^^^
+
+note: erroneous constant used
+ --> $DIR/format.rs:7:22
+ |
+LL | println!("{:?}", 0);
+ | ^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/format.rs:7:22
+ |
+LL | println!("{:?}", 0);
+ | ^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/const-eval/generic-slice.rs b/tests/ui/consts/const-eval/generic-slice.rs
new file mode 100644
index 000000000..21360a1c4
--- /dev/null
+++ b/tests/ui/consts/const-eval/generic-slice.rs
@@ -0,0 +1,31 @@
+// Several variants of #64945.
+
+// This struct is not important, we just use it to put `T` and `'a` in scope for our associated
+// consts.
+struct Generic<'a, T>(std::marker::PhantomData<&'a T>);
+
+impl<'a, T: 'static> Generic<'a, T> {
+ const EMPTY_SLICE: &'a [T] = {
+ let x: &'a [T] = &[];
+ x
+ };
+
+ const EMPTY_SLICE_REF: &'a &'static [T] = {
+ let x: &'static [T] = &[];
+ &x
+ //~^ ERROR `x` does not live long enough
+ };
+}
+
+static mut INTERIOR_MUT_AND_DROP: &'static [std::cell::RefCell<Vec<i32>>] = {
+ let x: &[_] = &[];
+ x
+};
+
+static mut INTERIOR_MUT_AND_DROP_REF: &'static &'static [std::cell::RefCell<Vec<i32>>] = {
+ let x: &[_] = &[];
+ &x
+ //~^ ERROR `x` does not live long enough
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/generic-slice.stderr b/tests/ui/consts/const-eval/generic-slice.stderr
new file mode 100644
index 000000000..c38088df4
--- /dev/null
+++ b/tests/ui/consts/const-eval/generic-slice.stderr
@@ -0,0 +1,30 @@
+error[E0597]: `x` does not live long enough
+ --> $DIR/generic-slice.rs:15:9
+ |
+LL | impl<'a, T: 'static> Generic<'a, T> {
+ | -- lifetime `'a` defined here
+...
+LL | &x
+ | ^^
+ | |
+ | borrowed value does not live long enough
+ | using this value as a constant requires that `x` is borrowed for `'a`
+LL |
+LL | };
+ | - `x` dropped here while still borrowed
+
+error[E0597]: `x` does not live long enough
+ --> $DIR/generic-slice.rs:27:5
+ |
+LL | &x
+ | ^^
+ | |
+ | borrowed value does not live long enough
+ | using this value as a static requires that `x` is borrowed for `'static`
+LL |
+LL | };
+ | - `x` dropped here while still borrowed
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs
new file mode 100644
index 000000000..ac9e8b64b
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.rs
@@ -0,0 +1,15 @@
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(const_mut_refs)]
+use std::intrinsics;
+
+const FOO: i32 = foo();
+const fn foo() -> i32 {
+ unsafe {
+ let _ = intrinsics::const_allocate(4, 3) as *mut i32;
+ //~^ error: evaluation of constant value failed
+ }
+ 1
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr
new file mode 100644
index 000000000..8f3b3d5f7
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_errors.stderr
@@ -0,0 +1,20 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/alloc_intrinsic_errors.rs:9:17
+ |
+LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ align has to be a power of 2, `3` is not a power of 2
+ |
+note: inside `foo`
+ --> $DIR/alloc_intrinsic_errors.rs:9:17
+ |
+LL | let _ = intrinsics::const_allocate(4, 3) as *mut i32;
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `FOO`
+ --> $DIR/alloc_intrinsic_errors.rs:6:18
+ |
+LL | const FOO: i32 = foo();
+ | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs
new file mode 100644
index 000000000..0a8fc7bca
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient.rs
@@ -0,0 +1,19 @@
+// run-pass
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(const_mut_refs)]
+use std::intrinsics;
+
+const FOO: &i32 = foo();
+
+const fn foo() -> &'static i32 {
+ let t = unsafe {
+ let i = intrinsics::const_allocate(4, 4) as * mut i32;
+ *i = 20;
+ i
+ };
+ unsafe { &*t }
+}
+fn main() {
+ assert_eq!(*FOO, 20)
+}
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.rs
new file mode 100644
index 000000000..f746f2700
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.rs
@@ -0,0 +1,18 @@
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(const_mut_refs)]
+use std::intrinsics;
+
+const FOO: *const i32 = foo();
+//~^ ERROR untyped pointers are not allowed in constant
+
+const fn foo() -> &'static i32 {
+ let t = unsafe {
+ let i = intrinsics::const_allocate(4, 4) as * mut i32;
+ *i = 20;
+ i
+ };
+ unsafe { &*t }
+}
+fn main() {
+}
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.stderr
new file mode 100644
index 000000000..00ab0dfc5
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_nontransient_fail.stderr
@@ -0,0 +1,8 @@
+error: untyped pointers are not allowed in constant
+ --> $DIR/alloc_intrinsic_nontransient_fail.rs:6:1
+ |
+LL | const FOO: *const i32 = foo();
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_transient.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_transient.rs
new file mode 100644
index 000000000..92193bb33
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_transient.rs
@@ -0,0 +1,19 @@
+// run-pass
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(const_mut_refs)]
+use std::intrinsics;
+
+const FOO: i32 = foo();
+
+const fn foo() -> i32 {
+ let t = unsafe {
+ let i = intrinsics::const_allocate(4, 4) as * mut i32;
+ *i = 20;
+ i
+ };
+ unsafe { *t }
+}
+fn main() {
+ assert_eq!(FOO, 20);
+}
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr
new file mode 100644
index 000000000..a0f4519ea
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.32bit.stderr
@@ -0,0 +1,14 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/alloc_intrinsic_uninit.rs:8:1
+ |
+LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
+ | ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ ╾─alloc2──╼ │ ╾──╼
+ }
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr
new file mode 100644
index 000000000..d2bffa425
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.64bit.stderr
@@ -0,0 +1,14 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/alloc_intrinsic_uninit.rs:8:1
+ |
+LL | const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
+ | ^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized memory, but expected an integer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ ╾───────alloc2────────╼ │ ╾──────╼
+ }
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs
new file mode 100644
index 000000000..b53c9ac7a
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_uninit.rs
@@ -0,0 +1,10 @@
+// stderr-per-bitwidth
+// compile-test
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(const_mut_refs)]
+use std::intrinsics;
+
+const BAR: &i32 = unsafe { &*(intrinsics::const_allocate(4, 4) as *mut i32) };
+//~^ error: it is undefined behavior to use this value
+fn main() {}
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.rs
new file mode 100644
index 000000000..77871c394
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.rs
@@ -0,0 +1,9 @@
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(const_mut_refs)]
+use std::intrinsics;
+
+const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32};
+//~^ error: untyped pointers are not allowed in constant
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.stderr b/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.stderr
new file mode 100644
index 000000000..36002b850
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_untyped.stderr
@@ -0,0 +1,8 @@
+error: untyped pointers are not allowed in constant
+ --> $DIR/alloc_intrinsic_untyped.rs:6:1
+ |
+LL | const BAR: *mut i32 = unsafe { intrinsics::const_allocate(4, 4) as *mut i32};
+ | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/tests/ui/consts/const-eval/heap/alloc_intrinsic_zero_sized.rs b/tests/ui/consts/const-eval/heap/alloc_intrinsic_zero_sized.rs
new file mode 100644
index 000000000..407e69d41
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/alloc_intrinsic_zero_sized.rs
@@ -0,0 +1,16 @@
+// run-pass
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(inline_const)]
+
+use std::intrinsics;
+
+struct ZST;
+
+fn main() {
+ const {
+ unsafe {
+ let _ = intrinsics::const_allocate(0, 0) as *mut ZST;
+ }
+ }
+}
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic.rs
new file mode 100644
index 000000000..aac90cd54
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic.rs
@@ -0,0 +1,36 @@
+// run-pass
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(const_mut_refs)]
+
+use std::intrinsics;
+
+const _X: () = unsafe {
+ let ptr = intrinsics::const_allocate(4, 4);
+ intrinsics::const_deallocate(ptr, 4, 4);
+};
+
+const Y: &u32 = unsafe {
+ let ptr = intrinsics::const_allocate(4, 4) as *mut u32;
+ *ptr = 42;
+ &*ptr
+};
+
+const Z: &u32 = &42;
+
+const _Z: () = unsafe {
+ let ptr1 = Y as *const _ as *mut u8;
+ intrinsics::const_deallocate(ptr1, 4, 4); // nop
+ intrinsics::const_deallocate(ptr1, 2, 4); // nop
+ intrinsics::const_deallocate(ptr1, 4, 2); // nop
+
+ let ptr2 = Z as *const _ as *mut u8;
+ intrinsics::const_deallocate(ptr2, 4, 4); // nop
+ intrinsics::const_deallocate(ptr2, 2, 4); // nop
+ intrinsics::const_deallocate(ptr2, 4, 2); // nop
+};
+
+fn main() {
+ assert_eq!(*Y, 42);
+ assert_eq!(*Z, 42);
+}
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs
new file mode 100644
index 000000000..b6d89a58d
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.rs
@@ -0,0 +1,22 @@
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(const_mut_refs)]
+
+use std::intrinsics;
+
+const _X: &'static u8 = unsafe {
+ let ptr = intrinsics::const_allocate(4, 4);
+ intrinsics::const_deallocate(ptr, 4, 4);
+ &*ptr
+ //~^ error: evaluation of constant value failed
+};
+
+const _Y: u8 = unsafe {
+ let ptr = intrinsics::const_allocate(4, 4);
+ let reference = &*ptr;
+ intrinsics::const_deallocate(ptr, 4, 4);
+ *reference
+ //~^ error: evaluation of constant value failed
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
new file mode 100644
index 000000000..4eb1c42e1
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_dangling.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/dealloc_intrinsic_dangling.rs:10:5
+ |
+LL | &*ptr
+ | ^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/dealloc_intrinsic_dangling.rs:18:5
+ |
+LL | *reference
+ | ^^^^^^^^^^ pointer to alloc4 was dereferenced after this allocation got freed
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.rs
new file mode 100644
index 000000000..4010b4769
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.rs
@@ -0,0 +1,13 @@
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+
+use std::intrinsics;
+
+const _X: () = unsafe {
+ let ptr = intrinsics::const_allocate(4, 4);
+ intrinsics::const_deallocate(ptr, 4, 4);
+ intrinsics::const_deallocate(ptr, 4, 4);
+ //~^ error: evaluation of constant value failed
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr
new file mode 100644
index 000000000..8177a0850
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_duplicate.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/dealloc_intrinsic_duplicate.rs:9:5
+ |
+LL | intrinsics::const_deallocate(ptr, 4, 4);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer to alloc2 was dereferenced after this allocation got freed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.rs
new file mode 100644
index 000000000..031d70fdc
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.rs
@@ -0,0 +1,29 @@
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+
+use std::intrinsics;
+
+const _X: () = unsafe {
+ let ptr = intrinsics::const_allocate(4, 4);
+ intrinsics::const_deallocate(ptr, 4, 2);
+ //~^ error: evaluation of constant value failed
+};
+const _Y: () = unsafe {
+ let ptr = intrinsics::const_allocate(4, 4);
+ intrinsics::const_deallocate(ptr, 2, 4);
+ //~^ error: evaluation of constant value failed
+};
+
+const _Z: () = unsafe {
+ let ptr = intrinsics::const_allocate(4, 4);
+ intrinsics::const_deallocate(ptr, 3, 4);
+ //~^ error: evaluation of constant value failed
+};
+
+const _W: () = unsafe {
+ let ptr = intrinsics::const_allocate(4, 4);
+ intrinsics::const_deallocate(ptr, 4, 3);
+ //~^ error: evaluation of constant value failed
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.stderr b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.stderr
new file mode 100644
index 000000000..650b409b1
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_incorrect_layout.stderr
@@ -0,0 +1,27 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/dealloc_intrinsic_incorrect_layout.rs:8:5
+ |
+LL | intrinsics::const_deallocate(ptr, 4, 2);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc2 has size 4 and alignment 4, but gave size 4 and alignment 2
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/dealloc_intrinsic_incorrect_layout.rs:13:5
+ |
+LL | intrinsics::const_deallocate(ptr, 2, 4);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc4 has size 4 and alignment 4, but gave size 2 and alignment 4
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/dealloc_intrinsic_incorrect_layout.rs:19:5
+ |
+LL | intrinsics::const_deallocate(ptr, 3, 4);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ incorrect layout on deallocation: alloc6 has size 4 and alignment 4, but gave size 3 and alignment 4
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/dealloc_intrinsic_incorrect_layout.rs:25:5
+ |
+LL | intrinsics::const_deallocate(ptr, 4, 3);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ align has to be a power of 2, `3` is not a power of 2
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/heap/dealloc_intrinsic_zero_sized.rs b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_zero_sized.rs
new file mode 100644
index 000000000..84fb4d2ea
--- /dev/null
+++ b/tests/ui/consts/const-eval/heap/dealloc_intrinsic_zero_sized.rs
@@ -0,0 +1,17 @@
+// run-pass
+#![feature(core_intrinsics)]
+#![feature(const_heap)]
+#![feature(inline_const)]
+
+use std::intrinsics;
+
+fn main() {
+ const {
+ unsafe {
+ let ptr1 = intrinsics::const_allocate(0, 0);
+ let ptr2 = intrinsics::const_allocate(0, 0);
+ intrinsics::const_deallocate(ptr1, 0, 0);
+ intrinsics::const_deallocate(ptr2, 0, 0);
+ }
+ }
+}
diff --git a/tests/ui/consts/const-eval/ice-generic-assoc-const.rs b/tests/ui/consts/const-eval/ice-generic-assoc-const.rs
new file mode 100644
index 000000000..e514682af
--- /dev/null
+++ b/tests/ui/consts/const-eval/ice-generic-assoc-const.rs
@@ -0,0 +1,16 @@
+// build-pass (tests post-monomorphisation failure)
+#![crate_type = "lib"]
+
+pub trait Nullable {
+ const NULL: Self;
+
+ fn is_null(&self) -> bool;
+}
+
+impl<T> Nullable for *const T {
+ const NULL: Self = core::ptr::null::<T>();
+
+ fn is_null(&self) -> bool {
+ *self == Self::NULL
+ }
+}
diff --git a/tests/ui/consts/const-eval/ice-packed.rs b/tests/ui/consts/const-eval/ice-packed.rs
new file mode 100644
index 000000000..4758a5a9d
--- /dev/null
+++ b/tests/ui/consts/const-eval/ice-packed.rs
@@ -0,0 +1,21 @@
+// Regression test for #50356: Compiler panic when using repr(packed)
+// associated constant in a match arm
+
+// check-pass
+#[derive(Copy, Clone, PartialEq, Eq)]
+#[repr(packed)]
+pub struct Num(u64);
+
+impl Num {
+ pub const ZERO: Self = Num(0);
+}
+
+pub fn decrement(a: Num) -> Num {
+ match a {
+ Num::ZERO => Num::ZERO,
+ a => Num(a.0 - 1)
+ }
+}
+
+fn main() {
+}
diff --git a/tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs b/tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs
new file mode 100644
index 000000000..bc2ea3f18
--- /dev/null
+++ b/tests/ui/consts/const-eval/index-out-of-bounds-never-type.rs
@@ -0,0 +1,21 @@
+// build-fail
+
+// Regression test for #66975
+#![warn(unconditional_panic)]
+#![feature(never_type)]
+
+struct PrintName<T>(T);
+
+impl<T> PrintName<T> {
+ const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
+ //~^ ERROR evaluation of `PrintName::<()>::VOID` failed
+
+}
+
+fn f<T>() {
+ let _ = PrintName::<T>::VOID;
+}
+
+pub fn main() {
+ f::<()>();
+}
diff --git a/tests/ui/consts/const-eval/index-out-of-bounds-never-type.stderr b/tests/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
new file mode 100644
index 000000000..8bcd03005
--- /dev/null
+++ b/tests/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of `PrintName::<()>::VOID` failed
+ --> $DIR/index-out-of-bounds-never-type.rs:10:61
+ |
+LL | const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
+ | ^^^^^ index out of bounds: the length is 0 but the index is 0
+
+note: the above error was encountered while instantiating `fn f::<()>`
+ --> $DIR/index-out-of-bounds-never-type.rs:20:5
+ |
+LL | f::<()>();
+ | ^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/index_out_of_bounds.rs b/tests/ui/consts/const-eval/index_out_of_bounds.rs
new file mode 100644
index 000000000..80e0d28fe
--- /dev/null
+++ b/tests/ui/consts/const-eval/index_out_of_bounds.rs
@@ -0,0 +1,4 @@
+static FOO: i32 = [][0];
+//~^ ERROR E0080
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/index_out_of_bounds.stderr b/tests/ui/consts/const-eval/index_out_of_bounds.stderr
new file mode 100644
index 000000000..8bb3a0c67
--- /dev/null
+++ b/tests/ui/consts/const-eval/index_out_of_bounds.stderr
@@ -0,0 +1,9 @@
+error[E0080]: could not evaluate static initializer
+ --> $DIR/index_out_of_bounds.rs:1:19
+ |
+LL | static FOO: i32 = [][0];
+ | ^^^^^ index out of bounds: the length is 0 but the index is 0
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/index_out_of_bounds_propagated.rs b/tests/ui/consts/const-eval/index_out_of_bounds_propagated.rs
new file mode 100644
index 000000000..608e6e112
--- /dev/null
+++ b/tests/ui/consts/const-eval/index_out_of_bounds_propagated.rs
@@ -0,0 +1,6 @@
+// build-fail
+
+fn main() {
+ let array = [std::env::args().len()];
+ array[1]; //~ ERROR operation will panic
+}
diff --git a/tests/ui/consts/const-eval/index_out_of_bounds_propagated.stderr b/tests/ui/consts/const-eval/index_out_of_bounds_propagated.stderr
new file mode 100644
index 000000000..d247d691d
--- /dev/null
+++ b/tests/ui/consts/const-eval/index_out_of_bounds_propagated.stderr
@@ -0,0 +1,10 @@
+error: this operation will panic at runtime
+ --> $DIR/index_out_of_bounds_propagated.rs:5:5
+ |
+LL | array[1];
+ | ^^^^^^^^ index out of bounds: the length is 1 but the index is 1
+ |
+ = note: `#[deny(unconditional_panic)]` on by default
+
+error: aborting due to previous error
+
diff --git a/tests/ui/consts/const-eval/infinite_loop.rs b/tests/ui/consts/const-eval/infinite_loop.rs
new file mode 100644
index 000000000..4babc9a28
--- /dev/null
+++ b/tests/ui/consts/const-eval/infinite_loop.rs
@@ -0,0 +1,12 @@
+fn main() {
+ // Tests the Collatz conjecture with an incorrect base case (0 instead of 1).
+ // The value of `n` will loop indefinitely (4 - 2 - 1 - 4).
+ let _ = [(); {
+ let mut n = 113383; // #20 in https://oeis.org/A006884
+ while n != 0 {
+ //~^ ERROR evaluation of constant value failed
+ n = if n % 2 == 0 { n/2 } else { 3*n + 1 };
+ }
+ n
+ }];
+}
diff --git a/tests/ui/consts/const-eval/infinite_loop.stderr b/tests/ui/consts/const-eval/infinite_loop.stderr
new file mode 100644
index 000000000..8b58cb279
--- /dev/null
+++ b/tests/ui/consts/const-eval/infinite_loop.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/infinite_loop.rs:6:15
+ |
+LL | while n != 0 {
+ | ^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-100878.rs b/tests/ui/consts/const-eval/issue-100878.rs
new file mode 100644
index 000000000..353ce5050
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-100878.rs
@@ -0,0 +1,8 @@
+// This checks that the const-eval ICE in issue #100878 does not recur.
+//
+// build-pass
+pub fn bitshift_data(data: [u8; 1]) -> u8 {
+ data[0] << 8
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/issue-104390.rs b/tests/ui/consts/const-eval/issue-104390.rs
new file mode 100644
index 000000000..602d81824
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-104390.rs
@@ -0,0 +1,10 @@
+fn f1() -> impl Sized { & 2E } //~ ERROR expected at least one digit in exponent
+fn f2() -> impl Sized { && 2E } //~ ERROR expected at least one digit in exponent
+fn f3() -> impl Sized { &'a 2E } //~ ERROR expected at least one digit in exponent
+//~^ ERROR borrow expressions cannot be annotated with lifetimes
+fn f4() -> impl Sized { &'static 2E } //~ ERROR expected at least one digit in exponent
+//~^ ERROR borrow expressions cannot be annotated with lifetimes
+fn f5() -> impl Sized { *& 2E } //~ ERROR expected at least one digit in exponent
+fn f6() -> impl Sized { &'_ 2E } //~ ERROR expected at least one digit in exponent
+//~^ ERROR borrow expressions cannot be annotated with lifetimes
+fn main() {}
diff --git a/tests/ui/consts/const-eval/issue-104390.stderr b/tests/ui/consts/const-eval/issue-104390.stderr
new file mode 100644
index 000000000..865b9996e
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-104390.stderr
@@ -0,0 +1,65 @@
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:1:27
+ |
+LL | fn f1() -> impl Sized { & 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:2:28
+ |
+LL | fn f2() -> impl Sized { && 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:3:29
+ |
+LL | fn f3() -> impl Sized { &'a 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:5:34
+ |
+LL | fn f4() -> impl Sized { &'static 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:7:28
+ |
+LL | fn f5() -> impl Sized { *& 2E }
+ | ^^
+
+error: expected at least one digit in exponent
+ --> $DIR/issue-104390.rs:8:29
+ |
+LL | fn f6() -> impl Sized { &'_ 2E }
+ | ^^
+
+error: borrow expressions cannot be annotated with lifetimes
+ --> $DIR/issue-104390.rs:3:25
+ |
+LL | fn f3() -> impl Sized { &'a 2E }
+ | ^--^^^
+ | |
+ | annotated with lifetime here
+ | help: remove the lifetime annotation
+
+error: borrow expressions cannot be annotated with lifetimes
+ --> $DIR/issue-104390.rs:5:25
+ |
+LL | fn f4() -> impl Sized { &'static 2E }
+ | ^-------^^^
+ | |
+ | annotated with lifetime here
+ | help: remove the lifetime annotation
+
+error: borrow expressions cannot be annotated with lifetimes
+ --> $DIR/issue-104390.rs:8:25
+ |
+LL | fn f6() -> impl Sized { &'_ 2E }
+ | ^--^^^
+ | |
+ | annotated with lifetime here
+ | help: remove the lifetime annotation
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/consts/const-eval/issue-43197.rs b/tests/ui/consts/const-eval/issue-43197.rs
new file mode 100644
index 000000000..145463f0a
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-43197.rs
@@ -0,0 +1,11 @@
+const fn foo(x: u32) -> u32 {
+ x
+}
+
+fn main() {
+ const X: u32 = 0 - 1;
+ //~^ ERROR constant
+ const Y: u32 = foo(0 - 1);
+ //~^ ERROR constant
+ println!("{} {}", X, Y);
+}
diff --git a/tests/ui/consts/const-eval/issue-43197.stderr b/tests/ui/consts/const-eval/issue-43197.stderr
new file mode 100644
index 000000000..c59f13e48
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-43197.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/issue-43197.rs:6:20
+ |
+LL | const X: u32 = 0 - 1;
+ | ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/issue-43197.rs:8:24
+ |
+LL | const Y: u32 = foo(0 - 1);
+ | ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-44578.rs b/tests/ui/consts/const-eval/issue-44578.rs
new file mode 100644
index 000000000..e4dcc6230
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-44578.rs
@@ -0,0 +1,27 @@
+// build-fail
+
+trait Foo {
+ const AMT: usize;
+}
+
+enum Bar<A, B> {
+ First(A),
+ Second(B),
+}
+
+impl<A: Foo, B: Foo> Foo for Bar<A, B> {
+ const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize]; //~ERROR evaluation of `<Bar<u16, u8> as Foo>::AMT` failed
+}
+
+impl Foo for u8 {
+ const AMT: usize = 1;
+}
+
+impl Foo for u16 {
+ const AMT: usize = 2;
+}
+
+fn main() {
+ println!("{}", <Bar<u16, u8> as Foo>::AMT);
+ //~^ constant
+}
diff --git a/tests/ui/consts/const-eval/issue-44578.stderr b/tests/ui/consts/const-eval/issue-44578.stderr
new file mode 100644
index 000000000..0cbf54480
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-44578.stderr
@@ -0,0 +1,39 @@
+error[E0080]: evaluation of `<Bar<u16, u8> as Foo>::AMT` failed
+ --> $DIR/issue-44578.rs:13:24
+ |
+LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1
+
+note: erroneous constant used
+ --> $DIR/issue-44578.rs:25:20
+ |
+LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/issue-44578.rs:25:20
+ |
+LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/issue-44578.rs:25:20
+ |
+LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/issue-44578.rs:25:20
+ |
+LL | println!("{}", <Bar<u16, u8> as Foo>::AMT);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: this note originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-47971.rs b/tests/ui/consts/const-eval/issue-47971.rs
new file mode 100644
index 000000000..b98e76031
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-47971.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+struct S(pub &'static u32, pub u32);
+
+const fn g(ss: &S) -> &u32 { &ss.1 }
+
+static T: S = S(g(&T), 0);
+
+fn main () { }
diff --git a/tests/ui/consts/const-eval/issue-49296.rs b/tests/ui/consts/const-eval/issue-49296.rs
new file mode 100644
index 000000000..917777a32
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-49296.rs
@@ -0,0 +1,14 @@
+// issue-49296: Unsafe shenigans in constants can result in missing errors
+
+use std::mem::transmute;
+
+const fn wat(x: u64) -> &'static u64 {
+ unsafe { transmute(&x) }
+}
+
+const X: u64 = *wat(42);
+//~^ ERROR evaluation of constant value failed
+
+fn main() {
+ println!("{}", X);
+}
diff --git a/tests/ui/consts/const-eval/issue-49296.stderr b/tests/ui/consts/const-eval/issue-49296.stderr
new file mode 100644
index 000000000..cc4f1594c
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-49296.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/issue-49296.rs:9:16
+ |
+LL | const X: u64 = *wat(42);
+ | ^^^^^^^^ pointer to alloc3 was dereferenced after this allocation got freed
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-50706.rs b/tests/ui/consts/const-eval/issue-50706.rs
new file mode 100644
index 000000000..a13c27f2e
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-50706.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+pub struct Stats;
+
+#[derive(PartialEq, Eq)]
+pub struct StatVariant {
+ pub id: u8,
+ _priv: (),
+}
+
+#[derive(PartialEq, Eq)]
+pub struct Stat {
+ pub variant: StatVariant,
+ pub index: usize,
+ _priv: (),
+}
+
+impl Stats {
+ pub const TEST: StatVariant = StatVariant{id: 0, _priv: (),};
+ #[allow(non_upper_case_globals)]
+ pub const A: Stat = Stat{
+ variant: Self::TEST,
+ index: 0,
+ _priv: (),};
+}
+
+impl Stat {
+ pub fn from_index(variant: StatVariant, index: usize) -> Option<Stat> {
+ let stat = Stat{variant, index, _priv: (),};
+ match stat {
+ Stats::A => Some(Stats::A),
+ _ => None,
+ }
+ }
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/issue-50814-2.rs b/tests/ui/consts/const-eval/issue-50814-2.rs
new file mode 100644
index 000000000..53eb7b149
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-50814-2.rs
@@ -0,0 +1,34 @@
+// build-fail
+
+trait C {
+ const BOO: usize;
+}
+
+trait Foo<T> {
+ const BAR: usize;
+}
+
+struct A<T>(T);
+
+impl<T: C> Foo<T> for A<T> {
+ const BAR: usize = [5, 6, 7][T::BOO]; //~ ERROR evaluation of `<A<()> as Foo<()>>::BAR` failed
+}
+
+fn foo<T: C>() -> &'static usize {
+ &<A<T> as Foo<T>>::BAR //~ constant
+}
+
+impl C for () {
+ const BOO: usize = 42;
+}
+
+impl C for u32 {
+ const BOO: usize = 1;
+}
+
+fn main() {
+ println!("{:x}", foo::<()>() as *const usize as usize);
+ println!("{:x}", foo::<u32>() as *const usize as usize);
+ println!("{:x}", foo::<()>());
+ println!("{:x}", foo::<u32>());
+}
diff --git a/tests/ui/consts/const-eval/issue-50814-2.stderr b/tests/ui/consts/const-eval/issue-50814-2.stderr
new file mode 100644
index 000000000..956f7aec9
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-50814-2.stderr
@@ -0,0 +1,21 @@
+error[E0080]: evaluation of `<A<()> as Foo<()>>::BAR` failed
+ --> $DIR/issue-50814-2.rs:14:24
+ |
+LL | const BAR: usize = [5, 6, 7][T::BOO];
+ | ^^^^^^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 42
+
+note: erroneous constant used
+ --> $DIR/issue-50814-2.rs:18:6
+ |
+LL | &<A<T> as Foo<T>>::BAR
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+note: the above error was encountered while instantiating `fn foo::<()>`
+ --> $DIR/issue-50814-2.rs:30:22
+ |
+LL | println!("{:x}", foo::<()>() as *const usize as usize);
+ | ^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-50814.rs b/tests/ui/consts/const-eval/issue-50814.rs
new file mode 100644
index 000000000..374ed1d93
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-50814.rs
@@ -0,0 +1,26 @@
+// build-fail
+
+trait Unsigned {
+ const MAX: u8;
+}
+
+struct U8(u8);
+impl Unsigned for U8 {
+ const MAX: u8 = 0xff;
+}
+
+struct Sum<A, B>(A, B);
+
+impl<A: Unsigned, B: Unsigned> Unsigned for Sum<A, B> {
+ const MAX: u8 = A::MAX + B::MAX;
+ //~^ ERROR evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
+}
+
+fn foo<T>(_: T) -> &'static u8 {
+ &Sum::<U8, U8>::MAX
+ //~^ constant
+}
+
+fn main() {
+ foo(0);
+}
diff --git a/tests/ui/consts/const-eval/issue-50814.stderr b/tests/ui/consts/const-eval/issue-50814.stderr
new file mode 100644
index 000000000..05b6271f4
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-50814.stderr
@@ -0,0 +1,21 @@
+error[E0080]: evaluation of `<Sum<U8, U8> as Unsigned>::MAX` failed
+ --> $DIR/issue-50814.rs:15:21
+ |
+LL | const MAX: u8 = A::MAX + B::MAX;
+ | ^^^^^^^^^^^^^^^ attempt to compute `u8::MAX + u8::MAX`, which would overflow
+
+note: erroneous constant used
+ --> $DIR/issue-50814.rs:20:6
+ |
+LL | &Sum::<U8, U8>::MAX
+ | ^^^^^^^^^^^^^^^^^^
+
+note: the above error was encountered while instantiating `fn foo::<i32>`
+ --> $DIR/issue-50814.rs:25:5
+ |
+LL | foo(0);
+ | ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-51300.rs b/tests/ui/consts/const-eval/issue-51300.rs
new file mode 100644
index 000000000..8e68e8c91
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-51300.rs
@@ -0,0 +1,31 @@
+// check-pass
+// https://github.com/rust-lang/rust/issues/51300
+
+#[derive(PartialEq, Eq, Clone, Copy)]
+pub struct Stat {
+ pub id: u8,
+ pub index: usize,
+}
+
+impl Stat {
+ pub const STUDENT_HAPPINESS: Stat = Stat{
+ id: 0,
+ index: 0,
+ };
+ pub const STUDENT_HUNGER: Stat = Stat{
+ id: 0,
+ index: Self::STUDENT_HAPPINESS.index + 1,
+ };
+
+}
+
+pub fn from_index(id: u8, index: usize) -> Option<Stat> {
+ let stat = Stat{id, index};
+ match stat {
+ Stat::STUDENT_HAPPINESS => Some(Stat::STUDENT_HAPPINESS),
+ Stat::STUDENT_HUNGER => Some(Stat::STUDENT_HUNGER),
+ _ => None,
+ }
+}
+
+fn main() { }
diff --git a/tests/ui/consts/const-eval/issue-52475.rs b/tests/ui/consts/const-eval/issue-52475.rs
new file mode 100644
index 000000000..ce65407bb
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-52475.rs
@@ -0,0 +1,11 @@
+fn main() {
+ let _ = [(); {
+ let mut x = &0;
+ let mut n = 0;
+ while n < 5 {
+ n = (n + 1) % 5; //~ ERROR evaluation of constant value failed
+ x = &0; // Materialize a new AllocId
+ }
+ 0
+ }];
+}
diff --git a/tests/ui/consts/const-eval/issue-52475.stderr b/tests/ui/consts/const-eval/issue-52475.stderr
new file mode 100644
index 000000000..8536ff02c
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-52475.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/issue-52475.rs:6:17
+ |
+LL | n = (n + 1) % 5;
+ | ^^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-53157.rs b/tests/ui/consts/const-eval/issue-53157.rs
new file mode 100644
index 000000000..850338625
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-53157.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+macro_rules! m {
+ () => {{
+ fn f(_: impl Sized) {}
+ f
+ }}
+}
+
+fn main() {
+ fn f() -> impl Sized {};
+ m!()(f());
+}
diff --git a/tests/ui/consts/const-eval/issue-53401.rs b/tests/ui/consts/const-eval/issue-53401.rs
new file mode 100644
index 000000000..31c946c3c
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-53401.rs
@@ -0,0 +1,11 @@
+// check-pass
+
+pub const STATIC_TRAIT: &dyn Test = &();
+
+fn main() {}
+
+pub trait Test {
+ fn test() where Self: Sized {}
+}
+
+impl Test for () {}
diff --git a/tests/ui/consts/const-eval/issue-55541.rs b/tests/ui/consts/const-eval/issue-55541.rs
new file mode 100644
index 000000000..fa5a493ab
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-55541.rs
@@ -0,0 +1,27 @@
+// check-pass
+
+// Test that we can handle newtypes wrapping extern types
+
+#![feature(extern_types)]
+
+use std::marker::PhantomData;
+
+extern "C" {
+ pub type ExternType;
+}
+unsafe impl Sync for ExternType {}
+static MAGIC_FFI_STATIC: u8 = 42;
+
+#[repr(transparent)]
+pub struct Wrapper(ExternType);
+pub static MAGIC_FFI_REF: &'static Wrapper = unsafe {
+ std::mem::transmute(&MAGIC_FFI_STATIC)
+};
+
+#[repr(transparent)]
+pub struct Wrapper2(PhantomData<Vec<i32>>, ExternType);
+pub static MAGIC_FFI_REF2: &'static Wrapper2 = unsafe {
+ std::mem::transmute(&MAGIC_FFI_STATIC)
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/issue-64908.rs b/tests/ui/consts/const-eval/issue-64908.rs
new file mode 100644
index 000000000..d2e095072
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-64908.rs
@@ -0,0 +1,20 @@
+// run-pass
+
+// This test verifies that the `ConstProp` pass doesn't cause an ICE when evaluating polymorphic
+// promoted MIR.
+
+pub trait ArrowPrimitiveType {
+ type Native;
+}
+
+pub fn new<T: ArrowPrimitiveType>() {
+ assert_eq!(0, std::mem::size_of::<T::Native>());
+}
+
+impl ArrowPrimitiveType for () {
+ type Native = ();
+}
+
+fn main() {
+ new::<()>();
+}
diff --git a/tests/ui/consts/const-eval/issue-64970.rs b/tests/ui/consts/const-eval/issue-64970.rs
new file mode 100644
index 000000000..ba530438f
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-64970.rs
@@ -0,0 +1,15 @@
+// run-pass
+
+fn main() {
+ foo(10);
+}
+
+fn foo(mut n: i32) {
+ if false {
+ n = 0i32;
+ }
+
+ if n > 0i32 {
+ let _ = 1i32 / n;
+ }
+}
diff --git a/tests/ui/consts/const-eval/issue-65394.rs b/tests/ui/consts/const-eval/issue-65394.rs
new file mode 100644
index 000000000..e6639826c
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-65394.rs
@@ -0,0 +1,13 @@
+// This test originated from #65394. We conservatively assume that `x` is still `LiveDrop` even
+// after it has been moved because a mutable reference to it exists at some point in the const body.
+//
+// We will likely have to change this behavior before we allow `&mut` in a `const`.
+
+const _: Vec<i32> = {
+ let mut x = Vec::<i32>::new(); //~ ERROR destructor of
+ let r = &mut x; //~ ERROR mutable references are not allowed in constants
+ let y = x;
+ y
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/issue-65394.stderr b/tests/ui/consts/const-eval/issue-65394.stderr
new file mode 100644
index 000000000..ae6f0e937
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-65394.stderr
@@ -0,0 +1,22 @@
+error[E0658]: mutable references are not allowed in constants
+ --> $DIR/issue-65394.rs:8:13
+ |
+LL | let r = &mut x;
+ | ^^^^^^
+ |
+ = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+ = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
+error[E0493]: destructor of `Vec<i32>` cannot be evaluated at compile-time
+ --> $DIR/issue-65394.rs:7:9
+ |
+LL | let mut x = Vec::<i32>::new();
+ | ^^^^^ the destructor for this type cannot be evaluated in constants
+...
+LL | };
+ | - value is dropped here
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0493, E0658.
+For more information about an error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/const-eval/issue-70723.rs b/tests/ui/consts/const-eval/issue-70723.rs
new file mode 100644
index 000000000..3c81afa67
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-70723.rs
@@ -0,0 +1,3 @@
+static _X: () = loop {}; //~ ERROR could not evaluate static initializer
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/issue-70723.stderr b/tests/ui/consts/const-eval/issue-70723.stderr
new file mode 100644
index 000000000..09fb3e060
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-70723.stderr
@@ -0,0 +1,9 @@
+error[E0080]: could not evaluate static initializer
+ --> $DIR/issue-70723.rs:1:17
+ |
+LL | static _X: () = loop {};
+ | ^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-70804-fn-subtyping.rs b/tests/ui/consts/const-eval/issue-70804-fn-subtyping.rs
new file mode 100644
index 000000000..abd1d32ab
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-70804-fn-subtyping.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+const fn nested(x: (for<'a> fn(&'a ()), String)) -> (fn(&'static ()), String) {
+ x
+}
+
+pub const TEST: (fn(&'static ()), String) = nested((|_x| (), String::new()));
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/issue-84957-const-str-as-bytes.rs b/tests/ui/consts/const-eval/issue-84957-const-str-as-bytes.rs
new file mode 100644
index 000000000..7e235c491
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-84957-const-str-as-bytes.rs
@@ -0,0 +1,28 @@
+// build-pass
+
+trait Foo {}
+
+struct Bar {
+ bytes: &'static [u8],
+ func: fn(&Box<dyn Foo>),
+}
+fn example(_: &Box<dyn Foo>) {}
+
+const BARS: &[Bar] = &[
+ Bar {
+ bytes: "0".as_bytes(),
+ func: example,
+ },
+ Bar {
+ bytes: "0".as_bytes(),
+ func: example,
+ },
+];
+
+fn main() {
+ let x = todo!();
+
+ for bar in BARS {
+ (bar.func)(&x);
+ }
+}
diff --git a/tests/ui/consts/const-eval/issue-85155.rs b/tests/ui/consts/const-eval/issue-85155.rs
new file mode 100644
index 000000000..c3216d53d
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-85155.rs
@@ -0,0 +1,21 @@
+// This is a test with a setup similar to issue 85155, which triggers a const eval error: a const
+// argument value is outside the range expected by the `stdarch` intrinsic.
+//
+// It's not the exact code mentioned in that issue because it depends both on `stdarch` intrinsics
+// only available on x64, and internal implementation details of `stdarch`. But mostly because these
+// are not important to trigger the diagnostics issue: it's specifically about the lack of context
+// in the diagnostics of post-monomorphization errors (PMEs) for consts, happening in a dependency.
+// Therefore, its setup is reproduced with an aux crate, which will similarly trigger a PME
+// depending on the const argument value, like the `stdarch` intrinsics would.
+//
+// aux-build: post_monomorphization_error.rs
+// build-fail: this is a post-monomorphization error, it passes check runs and requires building
+// to actually fail.
+
+extern crate post_monomorphization_error;
+
+fn main() {
+ // This function triggers a PME whenever the const argument does not fit in 1-bit.
+ post_monomorphization_error::stdarch_intrinsic::<2>();
+ //~^ NOTE the above error was encountered while instantiating
+}
diff --git a/tests/ui/consts/const-eval/issue-85155.stderr b/tests/ui/consts/const-eval/issue-85155.stderr
new file mode 100644
index 000000000..3d2c76b7e
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-85155.stderr
@@ -0,0 +1,15 @@
+error[E0080]: evaluation of `post_monomorphization_error::ValidateConstImm::<2, 0, 1>::VALID` failed
+ --> $DIR/auxiliary/post_monomorphization_error.rs:7:17
+ |
+LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to divide `1_usize` by zero
+
+note: the above error was encountered while instantiating `fn post_monomorphization_error::stdarch_intrinsic::<2>`
+ --> $DIR/issue-85155.rs:19:5
+ |
+LL | post_monomorphization_error::stdarch_intrinsic::<2>();
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/issue-85907.rs b/tests/ui/consts/const-eval/issue-85907.rs
new file mode 100644
index 000000000..6ae40ae6d
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-85907.rs
@@ -0,0 +1,7 @@
+const fn hey() -> usize {
+ panic!(123); //~ ERROR argument to `panic!()` in a const context must have type `&str`
+}
+
+fn main() {
+ let _: [u8; hey()] = todo!();
+}
diff --git a/tests/ui/consts/const-eval/issue-85907.stderr b/tests/ui/consts/const-eval/issue-85907.stderr
new file mode 100644
index 000000000..fd7b40572
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-85907.stderr
@@ -0,0 +1,10 @@
+error: argument to `panic!()` in a const context must have type `&str`
+ --> $DIR/issue-85907.rs:2:5
+ |
+LL | panic!(123);
+ | ^^^^^^^^^^^
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
diff --git a/tests/ui/consts/const-eval/issue-91827-extern-types.rs b/tests/ui/consts/const-eval/issue-91827-extern-types.rs
new file mode 100644
index 000000000..43c99799f
--- /dev/null
+++ b/tests/ui/consts/const-eval/issue-91827-extern-types.rs
@@ -0,0 +1,56 @@
+// run-pass
+//
+// Test that we can handle unsized types with an extern type tail part.
+// Regression test for issue #91827.
+
+#![feature(extern_types)]
+
+use std::ptr::addr_of;
+
+extern "C" {
+ type Opaque;
+}
+
+unsafe impl Sync for Opaque {}
+
+#[repr(C)]
+pub struct List<T> {
+ len: usize,
+ data: [T; 0],
+ tail: Opaque,
+}
+
+#[repr(C)]
+pub struct ListImpl<T, const N: usize> {
+ len: usize,
+ data: [T; N],
+}
+
+impl<T> List<T> {
+ const fn as_slice(&self) -> &[T] {
+ unsafe { std::slice::from_raw_parts(self.data.as_ptr(), self.len) }
+ }
+}
+
+impl<T, const N: usize> ListImpl<T, N> {
+ const fn as_list(&self) -> &List<T> {
+ unsafe { std::mem::transmute(self) }
+ }
+}
+
+pub static A: ListImpl<u128, 3> = ListImpl {
+ len: 3,
+ data: [5, 6, 7],
+};
+pub static A_REF: &'static List<u128> = A.as_list();
+pub static A_TAIL_OFFSET: isize = tail_offset(A.as_list());
+
+const fn tail_offset<T>(list: &List<T>) -> isize {
+ unsafe { (addr_of!(list.tail) as *const u8).offset_from(list as *const List<T> as *const u8) }
+}
+
+fn main() {
+ assert_eq!(A_REF.as_slice(), &[5, 6, 7]);
+ // Check that interpreter and code generation agree about the position of the tail field.
+ assert_eq!(A_TAIL_OFFSET, tail_offset(A_REF));
+}
diff --git a/tests/ui/consts/const-eval/livedrop.rs b/tests/ui/consts/const-eval/livedrop.rs
new file mode 100644
index 000000000..543f1f0ec
--- /dev/null
+++ b/tests/ui/consts/const-eval/livedrop.rs
@@ -0,0 +1,17 @@
+const _: Option<Vec<i32>> = {
+ let mut never_returned = Some(Vec::new());
+ let mut always_returned = None; //~ ERROR destructor of
+
+ let mut i = 0;
+ loop {
+ always_returned = never_returned;
+ never_returned = None;
+
+ i += 1;
+ if i == 10 {
+ break always_returned;
+ }
+ }
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/livedrop.stderr b/tests/ui/consts/const-eval/livedrop.stderr
new file mode 100644
index 000000000..d04fdb70e
--- /dev/null
+++ b/tests/ui/consts/const-eval/livedrop.stderr
@@ -0,0 +1,12 @@
+error[E0493]: destructor of `Option<Vec<i32>>` cannot be evaluated at compile-time
+ --> $DIR/livedrop.rs:3:9
+ |
+LL | let mut always_returned = None;
+ | ^^^^^^^^^^^^^^^^^^^ the destructor for this type cannot be evaluated in constants
+...
+LL | always_returned = never_returned;
+ | --------------- value is dropped here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/const-eval/match-test-ptr-null.rs b/tests/ui/consts/const-eval/match-test-ptr-null.rs
new file mode 100644
index 000000000..4af97b548
--- /dev/null
+++ b/tests/ui/consts/const-eval/match-test-ptr-null.rs
@@ -0,0 +1,12 @@
+fn main() {
+ // Make sure match uses the usual pointer comparison code path -- i.e., it should complain
+ // that pointer comparison is disallowed, not that parts of a pointer are accessed as raw
+ // bytes.
+ let _: [u8; 0] = [4; {
+ match &1 as *const i32 as usize {
+ //~^ ERROR pointers cannot be cast to integers during const eval
+ 0 => 42,
+ n => n,
+ }
+ }];
+}
diff --git a/tests/ui/consts/const-eval/match-test-ptr-null.stderr b/tests/ui/consts/const-eval/match-test-ptr-null.stderr
new file mode 100644
index 000000000..05c3951c1
--- /dev/null
+++ b/tests/ui/consts/const-eval/match-test-ptr-null.stderr
@@ -0,0 +1,11 @@
+error: pointers cannot be cast to integers during const eval
+ --> $DIR/match-test-ptr-null.rs:6:15
+ |
+LL | match &1 as *const i32 as usize {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: at compile-time, pointers do not have an integer value
+ = note: avoiding this restriction via `transmute`, `union`, or raw pointers leads to compile-time undefined behavior
+
+error: aborting due to previous error
+
diff --git a/tests/ui/consts/const-eval/mod-static-with-const-fn.rs b/tests/ui/consts/const-eval/mod-static-with-const-fn.rs
new file mode 100644
index 000000000..b6b74e67d
--- /dev/null
+++ b/tests/ui/consts/const-eval/mod-static-with-const-fn.rs
@@ -0,0 +1,22 @@
+// New test for #53818: modifying static memory at compile-time is not allowed.
+// The test should never compile successfully
+
+#![feature(const_mut_refs)]
+
+use std::cell::UnsafeCell;
+
+struct Foo(UnsafeCell<u32>);
+
+unsafe impl Send for Foo {}
+unsafe impl Sync for Foo {}
+
+static FOO: Foo = Foo(UnsafeCell::new(42));
+
+static BAR: () = unsafe {
+ *FOO.0.get() = 5;
+ //~^ ERROR could not evaluate static initializer
+};
+
+fn main() {
+ println!("{}", unsafe { *FOO.0.get() });
+}
diff --git a/tests/ui/consts/const-eval/mod-static-with-const-fn.stderr b/tests/ui/consts/const-eval/mod-static-with-const-fn.stderr
new file mode 100644
index 000000000..d127d1d45
--- /dev/null
+++ b/tests/ui/consts/const-eval/mod-static-with-const-fn.stderr
@@ -0,0 +1,9 @@
+error[E0080]: could not evaluate static initializer
+ --> $DIR/mod-static-with-const-fn.rs:16:5
+ |
+LL | *FOO.0.get() = 5;
+ | ^^^^^^^^^^^^^^^^ modifying a static's initial value from another static's initializer
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/no_lint_for_statically_known_error.rs b/tests/ui/consts/const-eval/no_lint_for_statically_known_error.rs
new file mode 100644
index 000000000..910ca3c4b
--- /dev/null
+++ b/tests/ui/consts/const-eval/no_lint_for_statically_known_error.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+// if `X` were used instead of `x`, `X - 10` would result in a lint.
+// This file should never produce a lint, no matter how the const
+// propagator is improved.
+
+#![deny(warnings)]
+
+const X: u32 = 5;
+
+fn main() {
+ let x = X;
+ if x > 10 {
+ println!("{}", x - 10);
+ } else {
+ println!("{}", 10 - x);
+ }
+}
diff --git a/tests/ui/consts/const-eval/nrvo.rs b/tests/ui/consts/const-eval/nrvo.rs
new file mode 100644
index 000000000..1d2c6acc0
--- /dev/null
+++ b/tests/ui/consts/const-eval/nrvo.rs
@@ -0,0 +1,26 @@
+// run-pass
+
+// When the NRVO is applied, the return place (`_0`) gets treated like a normal local. For example,
+// its address may be taken and it may be written to indirectly. Ensure that MIRI can handle this.
+
+#![feature(const_mut_refs)]
+
+#[inline(never)] // Try to ensure that MIR optimizations don't optimize this away.
+const fn init(buf: &mut [u8; 1024]) {
+ buf[33] = 3;
+ buf[444] = 4;
+}
+
+const fn nrvo() -> [u8; 1024] {
+ let mut buf = [0; 1024];
+ init(&mut buf);
+ buf
+}
+
+const BUF: [u8; 1024] = nrvo();
+
+fn main() {
+ assert_eq!(BUF[33], 3);
+ assert_eq!(BUF[19], 0);
+ assert_eq!(BUF[444], 4);
+}
diff --git a/tests/ui/consts/const-eval/panic-assoc-never-type.rs b/tests/ui/consts/const-eval/panic-assoc-never-type.rs
new file mode 100644
index 000000000..28edf5144
--- /dev/null
+++ b/tests/ui/consts/const-eval/panic-assoc-never-type.rs
@@ -0,0 +1,15 @@
+// build-fail
+
+// Regression test for #66975
+#![feature(never_type)]
+
+struct PrintName;
+
+impl PrintName {
+ const VOID: ! = panic!();
+ //~^ ERROR evaluation of constant value failed
+}
+
+fn main() {
+ let _ = PrintName::VOID; //~ constant
+}
diff --git a/tests/ui/consts/const-eval/panic-assoc-never-type.stderr b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr
new file mode 100644
index 000000000..7c36a3a42
--- /dev/null
+++ b/tests/ui/consts/const-eval/panic-assoc-never-type.stderr
@@ -0,0 +1,23 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/panic-assoc-never-type.rs:9:21
+ |
+LL | const VOID: ! = panic!();
+ | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/panic-assoc-never-type.rs:9:21
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+note: erroneous constant used
+ --> $DIR/panic-assoc-never-type.rs:14:13
+ |
+LL | let _ = PrintName::VOID;
+ | ^^^^^^^^^^^^^^^
+
+note: erroneous constant used
+ --> $DIR/panic-assoc-never-type.rs:14:13
+ |
+LL | let _ = PrintName::VOID;
+ | ^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/panic-never-type.rs b/tests/ui/consts/const-eval/panic-never-type.rs
new file mode 100644
index 000000000..a9e9026d9
--- /dev/null
+++ b/tests/ui/consts/const-eval/panic-never-type.rs
@@ -0,0 +1,9 @@
+// Regression test for #66975
+#![feature(never_type)]
+
+const VOID: ! = panic!();
+//~^ ERROR evaluation of constant value failed
+
+fn main() {
+ let _ = VOID;
+}
diff --git a/tests/ui/consts/const-eval/panic-never-type.stderr b/tests/ui/consts/const-eval/panic-never-type.stderr
new file mode 100644
index 000000000..6bff14a45
--- /dev/null
+++ b/tests/ui/consts/const-eval/panic-never-type.stderr
@@ -0,0 +1,11 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/panic-never-type.rs:4:17
+ |
+LL | const VOID: ! = panic!();
+ | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/panic-never-type.rs:4:17
+ |
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/partial_ptr_overwrite.rs b/tests/ui/consts/const-eval/partial_ptr_overwrite.rs
new file mode 100644
index 000000000..d6c768868
--- /dev/null
+++ b/tests/ui/consts/const-eval/partial_ptr_overwrite.rs
@@ -0,0 +1,14 @@
+// Test for the behavior described in <https://github.com/rust-lang/rust/issues/87184>.
+#![feature(const_mut_refs)]
+
+const PARTIAL_OVERWRITE: () = {
+ let mut p = &42;
+ unsafe {
+ let ptr: *mut _ = &mut p;
+ *(ptr as *mut u8) = 123; //~ ERROR constant
+ //~| unable to overwrite parts of a pointer
+ }
+ let x = *p;
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr b/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr
new file mode 100644
index 000000000..13ca4379b
--- /dev/null
+++ b/tests/ui/consts/const-eval/partial_ptr_overwrite.stderr
@@ -0,0 +1,12 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/partial_ptr_overwrite.rs:8:9
+ |
+LL | *(ptr as *mut u8) = 123;
+ | ^^^^^^^^^^^^^^^^^^^^^^^ unable to overwrite parts of a pointer in memory at alloc4
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/promote-static.rs b/tests/ui/consts/const-eval/promote-static.rs
new file mode 100644
index 000000000..d3c663c53
--- /dev/null
+++ b/tests/ui/consts/const-eval/promote-static.rs
@@ -0,0 +1,14 @@
+// regression test for #67609.
+
+// check-pass
+
+static NONE: Option<String> = None;
+
+static NONE_REF_REF: &&Option<String> = {
+ let x = &&NONE;
+ x
+};
+
+fn main() {
+ println!("{:?}", NONE_REF_REF);
+}
diff --git a/tests/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs b/tests/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs
new file mode 100644
index 000000000..edda10e6e
--- /dev/null
+++ b/tests/ui/consts/const-eval/promote_mutable_zst_mir_borrowck.rs
@@ -0,0 +1,5 @@
+// check-pass
+
+pub fn main() {
+ let y: &'static mut [u8; 0] = &mut [];
+}
diff --git a/tests/ui/consts/const-eval/promoted_const_fn_fail.rs b/tests/ui/consts/const-eval/promoted_const_fn_fail.rs
new file mode 100644
index 000000000..656dd33e1
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_const_fn_fail.rs
@@ -0,0 +1,20 @@
+#[repr(C)]
+union Bar {
+ a: &'static u8,
+ b: usize,
+}
+
+const fn bar() -> u8 {
+ unsafe {
+ // this will error as long as this test
+ // is run on a system whose pointers need more
+ // than 8 bits
+ Bar { a: &42 }.b as u8
+ }
+}
+
+fn main() {
+ let x: &'static u8 = &(bar() + 1); //~ ERROR temporary value dropped while borrowed
+ let y = *x;
+ unreachable!();
+}
diff --git a/tests/ui/consts/const-eval/promoted_const_fn_fail.stderr b/tests/ui/consts/const-eval/promoted_const_fn_fail.stderr
new file mode 100644
index 000000000..2d4e7c83d
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_const_fn_fail.stderr
@@ -0,0 +1,14 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_fn_fail.rs:17:27
+ |
+LL | let x: &'static u8 = &(bar() + 1);
+ | ----------- ^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs b/tests/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs
new file mode 100644
index 000000000..5009dbcb9
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.rs
@@ -0,0 +1,22 @@
+#[repr(C)]
+union Bar {
+ a: &'static u8,
+ b: usize,
+}
+
+const fn bar() -> u8 {
+ unsafe {
+ // This will error as long as this test is run on a system whose
+ // pointers need more than 8 bits.
+ Bar { a: &42 }.b as u8
+ }
+}
+
+fn main() {
+ // This will compile, but then hard-abort at runtime.
+ // FIXME(oli-obk): this should instead panic (not hard-abort) at runtime.
+ let x: &'static u8 = &(bar() + 1);
+ //~^ ERROR temporary value dropped while borrowed
+ let y = *x;
+ unreachable!();
+}
diff --git a/tests/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr b/tests/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr
new file mode 100644
index 000000000..9ebae3a18
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_const_fn_fail_deny_const_err.stderr
@@ -0,0 +1,14 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_const_fn_fail_deny_const_err.rs:18:27
+ |
+LL | let x: &'static u8 = &(bar() + 1);
+ | ----------- ^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/const-eval/promoted_errors.noopt.stderr b/tests/ui/consts/const-eval/promoted_errors.noopt.stderr
new file mode 100644
index 000000000..2a254bfde
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_errors.noopt.stderr
@@ -0,0 +1,44 @@
+warning: this arithmetic operation will overflow
+ --> $DIR/promoted_errors.rs:15:5
+ |
+LL | 0 - 1
+ | ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:9
+ |
+LL | #![warn(arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:19:5
+ |
+LL | 1 / 0
+ | ^^^^^ attempt to divide `1_i32` by zero
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:30
+ |
+LL | #![warn(arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:23:5
+ |
+LL | 1 / (1 - 1)
+ | ^^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:27:5
+ |
+LL | 1 / (false as i32)
+ | ^^^^^^^^^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:31:5
+ |
+LL | [1, 2, 3][4]
+ | ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+warning: 5 warnings emitted
+
diff --git a/tests/ui/consts/const-eval/promoted_errors.opt.stderr b/tests/ui/consts/const-eval/promoted_errors.opt.stderr
new file mode 100644
index 000000000..2a254bfde
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_errors.opt.stderr
@@ -0,0 +1,44 @@
+warning: this arithmetic operation will overflow
+ --> $DIR/promoted_errors.rs:15:5
+ |
+LL | 0 - 1
+ | ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:9
+ |
+LL | #![warn(arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:19:5
+ |
+LL | 1 / 0
+ | ^^^^^ attempt to divide `1_i32` by zero
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:30
+ |
+LL | #![warn(arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:23:5
+ |
+LL | 1 / (1 - 1)
+ | ^^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:27:5
+ |
+LL | 1 / (false as i32)
+ | ^^^^^^^^^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:31:5
+ |
+LL | [1, 2, 3][4]
+ | ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+warning: 5 warnings emitted
+
diff --git a/tests/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr b/tests/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
new file mode 100644
index 000000000..2a254bfde
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr
@@ -0,0 +1,44 @@
+warning: this arithmetic operation will overflow
+ --> $DIR/promoted_errors.rs:15:5
+ |
+LL | 0 - 1
+ | ^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:9
+ |
+LL | #![warn(arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:19:5
+ |
+LL | 1 / 0
+ | ^^^^^ attempt to divide `1_i32` by zero
+ |
+note: the lint level is defined here
+ --> $DIR/promoted_errors.rs:11:30
+ |
+LL | #![warn(arithmetic_overflow, unconditional_panic)]
+ | ^^^^^^^^^^^^^^^^^^^
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:23:5
+ |
+LL | 1 / (1 - 1)
+ | ^^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:27:5
+ |
+LL | 1 / (false as i32)
+ | ^^^^^^^^^^^^^^^^^^ attempt to divide `1_i32` by zero
+
+warning: this operation will panic at runtime
+ --> $DIR/promoted_errors.rs:31:5
+ |
+LL | [1, 2, 3][4]
+ | ^^^^^^^^^^^^ index out of bounds: the length is 3 but the index is 4
+
+warning: 5 warnings emitted
+
diff --git a/tests/ui/consts/const-eval/promoted_errors.rs b/tests/ui/consts/const-eval/promoted_errors.rs
new file mode 100644
index 000000000..2c42d0356
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_errors.rs
@@ -0,0 +1,52 @@
+// revisions: noopt opt opt_with_overflow_checks
+//[noopt]compile-flags: -C opt-level=0
+//[opt]compile-flags: -O
+//[opt_with_overflow_checks]compile-flags: -C overflow-checks=on -O
+
+// build-pass
+// ignore-pass (test emits codegen-time warnings and verifies that they are not errors)
+
+//! This test ensures that when we promote code that fails to evaluate, the build still succeeds.
+
+#![warn(arithmetic_overflow, unconditional_panic)]
+
+// The only way to have promoteds that fail is in `const fn` called from `const`/`static`.
+const fn overflow() -> u32 {
+ 0 - 1
+ //~^ WARN this arithmetic operation will overflow
+}
+const fn div_by_zero1() -> i32 {
+ 1 / 0
+ //~^ WARN this operation will panic at runtime
+}
+const fn div_by_zero2() -> i32 {
+ 1 / (1 - 1)
+ //~^ WARN this operation will panic at runtime
+}
+const fn div_by_zero3() -> i32 {
+ 1 / (false as i32)
+ //~^ WARN this operation will panic at runtime
+}
+const fn oob() -> i32 {
+ [1, 2, 3][4]
+ //~^ WARN this operation will panic at runtime
+}
+
+const fn mk_false() -> bool { false }
+
+// An actually used constant referencing failing promoteds in dead code.
+// This needs to always work.
+const Y: () = {
+ if mk_false() {
+ let _x: &'static u32 = &overflow();
+ let _x: &'static i32 = &div_by_zero1();
+ let _x: &'static i32 = &div_by_zero2();
+ let _x: &'static i32 = &div_by_zero3();
+ let _x: &'static i32 = &oob();
+ }
+ ()
+};
+
+fn main() {
+ let _y = Y;
+}
diff --git a/tests/ui/consts/const-eval/promoted_raw_ptr_ops.rs b/tests/ui/consts/const-eval/promoted_raw_ptr_ops.rs
new file mode 100644
index 000000000..1800b0a97
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_raw_ptr_ops.rs
@@ -0,0 +1,10 @@
+fn main() {
+ let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
+ //~^ ERROR temporary value dropped while borrowed
+ let y: &'static usize = &(&1 as *const i32 as usize + 1);
+ //~^ ERROR temporary value dropped while borrowed
+ let z: &'static i32 = &(unsafe { *(42 as *const i32) });
+ //~^ ERROR temporary value dropped while borrowed
+ let a: &'static bool = &(main as fn() == main as fn());
+ //~^ ERROR temporary value dropped while borrowed
+}
diff --git a/tests/ui/consts/const-eval/promoted_raw_ptr_ops.stderr b/tests/ui/consts/const-eval/promoted_raw_ptr_ops.stderr
new file mode 100644
index 000000000..01fcf2ec2
--- /dev/null
+++ b/tests/ui/consts/const-eval/promoted_raw_ptr_ops.stderr
@@ -0,0 +1,47 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_raw_ptr_ops.rs:2:29
+ |
+LL | let x: &'static bool = &(42 as *const i32 == 43 as *const i32);
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_raw_ptr_ops.rs:4:30
+ |
+LL | let y: &'static usize = &(&1 as *const i32 as usize + 1);
+ | -------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_raw_ptr_ops.rs:6:28
+ |
+LL | let z: &'static i32 = &(unsafe { *(42 as *const i32) });
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+...
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/promoted_raw_ptr_ops.rs:8:29
+ |
+LL | let a: &'static bool = &(main as fn() == main as fn());
+ | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL |
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/const-eval/raw-bytes.32bit.stderr b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr
new file mode 100644
index 000000000..91a426580
--- /dev/null
+++ b/tests/ui/consts/const-eval/raw-bytes.32bit.stderr
@@ -0,0 +1,596 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:20:1
+ |
+LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x00000001, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 01 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:28:1
+ |
+LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x00000000, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 00 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:42:1
+ |
+LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 01 │ .
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:44:1
+ |
+LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 03 │ .
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:50:1
+ |
+LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ 78 00 00 00 ff ff ff ff │ x.......
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:54:1
+ |
+LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 00 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:57:1
+ |
+LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 00 │ .
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:59:1
+ |
+LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 00 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:65:1
+ |
+LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 2a 00 00 00 │ *...
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:71:1
+ |
+LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 14 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:74:1
+ |
+LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ 00 00 00 00 ╾ALLOC_ID╼ │ ....╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:82:1
+ |
+LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
+ | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ ╾ALLOC_ID╼ │ ╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:86:1
+ |
+LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ ╾ALLOC_ID╼ │ ╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:90:1
+ |
+LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 00 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:93:1
+ |
+LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 00 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:96:1
+ |
+LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (address 0x539 is unallocated)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 39 05 00 00 │ 9...
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:99:1
+ |
+LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (address 0x539 is unallocated)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 39 05 00 00 │ 9...
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:102:1
+ |
+LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 00 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:104:1
+ |
+LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 0d 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:106:1
+ |
+LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a function pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ ╾ALLOC_ID╼ │ ╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:112:1
+ |
+LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type Bar
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 01 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:137:1
+ |
+LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ e7 03 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:139:1
+ |
+LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ ff ff ff ff │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:141:1
+ |
+LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ ff ff ff ff │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:144:1
+ |
+LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized data in `str`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:146:1
+ |
+LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered uninitialized data in `str`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:148:1
+ |
+LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:152:1
+ |
+LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ e7 03 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:154:1
+ |
+LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ ff ff ff 7f │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:157:1
+ |
+LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ e7 03 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:160:1
+ |
+LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ ╾ALLOC_ID╼ │ ╾──╼
+ }
+
+note: erroneous constant used
+ --> $DIR/raw-bytes.rs:160:40
+ |
+LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:166:1
+ |
+LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ ╾ALLOC_ID╼ │ ╾──╼
+ }
+
+note: erroneous constant used
+ --> $DIR/raw-bytes.rs:166:42
+ |
+LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:170:1
+ |
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ ╾ALLOC_ID╼ │ ╾──╼
+ }
+
+note: erroneous constant used
+ --> $DIR/raw-bytes.rs:170:42
+ |
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:175:1
+ |
+LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:179:1
+ |
+LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:183:1
+ |
+LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:186:1
+ |
+LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:190:1
+ |
+LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:194:1
+ |
+LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 00 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:196:1
+ |
+LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──╼╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:201:1
+ |
+LL | const LAYOUT_INVALID_ZERO: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .align.0.<enum-tag>: encountered 0x00000000, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ 00 10 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:205:1
+ |
+LL | const LAYOUT_INVALID_THREE: Layout = unsafe { Layout::from_size_align_unchecked(9, 3) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .align.0.<enum-tag>: encountered 0x00000003, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ 09 00 00 00 03 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:209:1
+ |
+LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
+ | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type [!; 1]
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 01 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:210:1
+ |
+LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) };
+ | ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ 01 00 00 00 01 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:211:1
+ |
+LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
+ | ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ 01 00 00 00 2a 00 00 00 │ ....*...
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:215:1
+ |
+LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) };
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized bytes
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:218:1
+ |
+LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) };
+ | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:221:1
+ |
+LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
+ | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:225:1
+ |
+LL | pub static S7: &[u16] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[1]: encountered uninitialized bytes
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID+0x2╼ 04 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:232:1
+ |
+LL | pub static R4: &[u8] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized bytes
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 01 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:237:1
+ |
+LL | pub static R5: &[u8] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:242:1
+ |
+LL | pub static R6: &[bool] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾ALLOC_ID╼ 04 00 00 00 │ ╾──╼....
+ }
+
+error: aborting due to 52 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr
new file mode 100644
index 000000000..e4c5e62f6
--- /dev/null
+++ b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr
@@ -0,0 +1,596 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:20:1
+ |
+LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x0000000000000001, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 01 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:28:1
+ |
+LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x0000000000000000, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 00 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:42:1
+ |
+LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 01 │ .
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:44:1
+ |
+LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 03 │ .
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:50:1
+ |
+LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ 78 00 00 00 ff ff ff ff │ x.......
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:54:1
+ |
+LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 00 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:57:1
+ |
+LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 00 │ .
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:59:1
+ |
+LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 00 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:65:1
+ |
+LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 2a 00 00 00 │ *...
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:71:1
+ |
+LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 4, align: 4) {
+ 14 00 00 00 │ ....
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:74:1
+ |
+LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ 00 00 00 00 00 00 00 00 ╾ALLOC_ID╼ │ ........╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:82:1
+ |
+LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
+ | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ ╾ALLOC_ID╼ │ ╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:86:1
+ |
+LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ ╾ALLOC_ID╼ │ ╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:90:1
+ |
+LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 00 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:93:1
+ |
+LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 00 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:96:1
+ |
+LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (address 0x539 is unallocated)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 39 05 00 00 00 00 00 00 │ 9.......
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:99:1
+ |
+LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (address 0x539 is unallocated)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 39 05 00 00 00 00 00 00 │ 9.......
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:102:1
+ |
+LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 00 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:104:1
+ |
+LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 0d 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:106:1
+ |
+LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a function pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ ╾ALLOC_ID╼ │ ╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:112:1
+ |
+LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type Bar
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 01 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:137:1
+ |
+LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:139:1
+ |
+LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ ff ff ff ff ff ff ff ff │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:141:1
+ |
+LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ ff ff ff ff ff ff ff ff │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:144:1
+ |
+LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized data in `str`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:146:1
+ |
+LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered uninitialized data in `str`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:148:1
+ |
+LL | const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:152:1
+ |
+LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:154:1
+ |
+LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ ff ff ff ff ff ff ff 7f │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:157:1
+ |
+LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ e7 03 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:160:1
+ |
+LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ ╾ALLOC_ID╼ │ ╾──────╼
+ }
+
+note: erroneous constant used
+ --> $DIR/raw-bytes.rs:160:40
+ |
+LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:166:1
+ |
+LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ ╾ALLOC_ID╼ │ ╾──────╼
+ }
+
+note: erroneous constant used
+ --> $DIR/raw-bytes.rs:166:42
+ |
+LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:170:1
+ |
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ ╾ALLOC_ID╼ │ ╾──────╼
+ }
+
+note: erroneous constant used
+ --> $DIR/raw-bytes.rs:170:42
+ |
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:175:1
+ |
+LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:179:1
+ |
+LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:183:1
+ |
+LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:186:1
+ |
+LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:190:1
+ |
+LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:194:1
+ |
+LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 00 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:196:1
+ |
+LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ ╾ALLOC_ID╼ │ ╾──────╼╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:201:1
+ |
+LL | const LAYOUT_INVALID_ZERO: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .align.0.<enum-tag>: encountered 0x0000000000000000, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:205:1
+ |
+LL | const LAYOUT_INVALID_THREE: Layout = unsafe { Layout::from_size_align_unchecked(9, 3) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .align.0.<enum-tag>: encountered 0x0000000000000003, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ 09 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 │ ................
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:209:1
+ |
+LL | const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) };
+ | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type [!; 1]
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 8) {
+ 01 00 00 00 00 00 00 00 │ ........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:210:1
+ |
+LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) };
+ | ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 │ ................
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:211:1
+ |
+LL | const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) };
+ | ^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered a value of the never type `!`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ 01 00 00 00 00 00 00 00 2a 00 00 00 00 00 00 00 │ ........*.......
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:215:1
+ |
+LL | pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) };
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized bytes
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:218:1
+ |
+LL | pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) };
+ | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:221:1
+ |
+LL | pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
+ | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:225:1
+ |
+LL | pub static S7: &[u16] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[1]: encountered uninitialized bytes
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID+0x2╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:232:1
+ |
+LL | pub static R4: &[u8] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered uninitialized bytes
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 01 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:237:1
+ |
+LL | pub static R5: &[u8] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 08 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/raw-bytes.rs:242:1
+ |
+LL | pub static R6: &[bool] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x11, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾ALLOC_ID╼ 04 00 00 00 00 00 00 00 │ ╾──────╼........
+ }
+
+error: aborting due to 52 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/raw-bytes.rs b/tests/ui/consts/const-eval/raw-bytes.rs
new file mode 100644
index 000000000..6c1238c0a
--- /dev/null
+++ b/tests/ui/consts/const-eval/raw-bytes.rs
@@ -0,0 +1,263 @@
+// stderr-per-bitwidth
+// ignore-endian-big
+// ignore-tidy-linelength
+// normalize-stderr-test "╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼" -> "╾ALLOC_ID$2╼"
+// normalize-stderr-test "alloc\d+" -> "allocN"
+#![feature(never_type, rustc_attrs, ptr_metadata, slice_from_ptr_range, const_slice_from_ptr_range)]
+#![allow(invalid_value)]
+
+use std::mem;
+use std::alloc::Layout;
+use std::ptr::NonNull;
+use std::num::{NonZeroU8, NonZeroUsize};
+use std::slice::{from_ptr_range, from_raw_parts};
+
+#[repr(usize)]
+#[derive(Copy, Clone)]
+enum Enum {
+ A = 0,
+}
+const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
+//~^ ERROR is undefined behavior
+
+#[repr(usize)]
+#[derive(Copy, Clone)]
+enum Enum2 {
+ A = 2,
+}
+const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
+//~^ ERROR is undefined behavior
+
+#[derive(Copy, Clone)]
+enum Never {}
+
+// An enum with 3 variants of which some are uninhabited -- so the uninhabited variants *do*
+// have a discriminant.
+enum UninhDiscriminant {
+ A,
+ B(!),
+ C,
+ D(Never),
+}
+const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
+//~^ ERROR is undefined behavior
+const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
+//~^ ERROR is undefined behavior
+
+// Invalid enum field content (mostly to test printing of paths for enum tuple
+// variants and tuples).
+// Need to create something which does not clash with enum layout optimizations.
+const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
+//~^ ERROR is undefined behavior
+
+
+const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
+//~^ ERROR it is undefined behavior to use this value
+const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+#[rustc_layout_scalar_valid_range_start(10)]
+#[rustc_layout_scalar_valid_range_end(30)]
+struct RestrictedRange1(u32);
+const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
+//~^ ERROR it is undefined behavior to use this value
+
+#[rustc_layout_scalar_valid_range_start(30)]
+#[rustc_layout_scalar_valid_range_end(10)]
+struct RestrictedRange2(u32);
+const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
+//~^ ERROR it is undefined behavior to use this value
+
+const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
+//~^ ERROR it is undefined behavior to use this value
+ let x: &dyn Send = &42;
+ let meta = std::ptr::metadata(x);
+ mem::transmute((0_usize, meta))
+};
+
+
+const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
+//~^ ERROR it is undefined behavior to use this value
+//~| constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1)
+
+const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
+//~^ ERROR it is undefined behavior to use this value
+//~| constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1)
+
+const NULL: &u16 = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
+//~^ ERROR it is undefined behavior to use this value
+const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
+//~^ ERROR it is undefined behavior to use this value
+
+#[derive(Copy, Clone)]
+enum Bar {}
+
+const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+
+/// A newtype wrapper to prevent MIR generation from inserting reborrows that would affect the error
+/// message.
+#[repr(transparent)]
+struct W<T>(T);
+
+#[repr(C)]
+union MaybeUninit<T: Copy> {
+ uninit: (),
+ init: T,
+}
+
+trait Trait {}
+impl Trait for bool {}
+
+// custom unsized type
+struct MyStr(str);
+
+// custom unsized type with sized fields
+struct MySlice<T: ?Sized>(bool, T);
+type MySliceBool = MySlice<[bool]>;
+
+const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
+//~^ ERROR it is undefined behavior to use this value
+const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
+//~^ ERROR it is undefined behavior to use this value
+const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
+//~^ ERROR it is undefined behavior to use this value
+
+const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+//~^ ERROR it is undefined behavior to use this value
+const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+//~^ ERROR it is undefined behavior to use this value
+const MYSTR_NO_INIT_ISSUE83182: &MyStr = unsafe { mem::transmute::<&[_], _>(&[&()]) };
+//~^ ERROR: it is undefined behavior to use this value
+
+// # slice
+const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
+//~^ ERROR it is undefined behavior to use this value
+const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
+//~^ ERROR it is undefined behavior to use this value
+// bad slice box: length too big
+const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
+//~^ ERROR it is undefined behavior to use this value
+// bad data *inside* the slice
+const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+//~^ ERROR it is undefined behavior to use this value
+//~| constant
+
+
+// bad: sized field is not okay
+const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+//~^ ERROR it is undefined behavior to use this value
+//~| constant
+// bad: unsized part is not okay
+const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+//~^ ERROR it is undefined behavior to use this value
+//~| constant
+
+// bad trait object
+const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a vtable
+// bad trait object
+const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a vtable
+// bad trait object
+const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a vtable
+const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a vtable
+// bad data *inside* the trait object
+const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a boolean
+
+const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
+//~^ ERROR it is undefined behavior to use this value
+const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
+//~^ ERROR it is undefined behavior to use this value
+
+
+// not ok, since alignment needs to be non-zero.
+const LAYOUT_INVALID_ZERO: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
+//~^ ERROR it is undefined behavior to use this value
+
+// not ok, since alignment needs to be a power of two.
+const LAYOUT_INVALID_THREE: Layout = unsafe { Layout::from_size_align_unchecked(9, 3) };
+//~^ ERROR it is undefined behavior to use this value
+
+
+const _: &[!; 1] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior
+const _: &[!] = unsafe { &*(1_usize as *const [!; 1]) }; //~ ERROR undefined behavior
+const _: &[!] = unsafe { &*(1_usize as *const [!; 42]) }; //~ ERROR undefined behavior
+
+
+// Reading uninitialized data
+pub static S4: &[u8] = unsafe { from_raw_parts((&D1) as *const _ as _, 1) };
+//~^ ERROR: it is undefined behavior to use this value
+// Reinterpret pointers as integers (UB in CTFE.)
+pub static S5: &[u8] = unsafe { from_raw_parts((&D3) as *const _ as _, mem::size_of::<&u32>()) };
+//~^ ERROR: it is undefined behavior to use this value
+// Layout mismatch
+pub static S6: &[bool] = unsafe { from_raw_parts((&D0) as *const _ as _, 4) };
+//~^ ERROR: it is undefined behavior to use this value
+
+// Reading padding is not ok
+pub static S7: &[u16] = unsafe {
+ //~^ ERROR: it is undefined behavior to use this value
+ let ptr = (&D2 as *const Struct as *const u16).add(1);
+
+ from_raw_parts(ptr, 4)
+};
+
+pub static R4: &[u8] = unsafe {
+ //~^ ERROR: it is undefined behavior to use this value
+ let ptr = (&D1) as *const mem::MaybeUninit<&u32> as *const u8;
+ from_ptr_range(ptr..ptr.add(1))
+};
+pub static R5: &[u8] = unsafe {
+ //~^ ERROR: it is undefined behavior to use this value
+ let ptr = &D3 as *const &u32;
+ from_ptr_range(ptr.cast()..ptr.add(1).cast())
+};
+pub static R6: &[bool] = unsafe {
+ //~^ ERROR: it is undefined behavior to use this value
+ let ptr = &D0 as *const u32 as *const bool;
+ from_ptr_range(ptr..ptr.add(4))
+};
+
+const D0: u32 = 0x11111111; // Constant chosen for endianness-independent behavior.
+const D1: mem::MaybeUninit<&u32> = mem::MaybeUninit::uninit();
+const D2: Struct = Struct { a: 1, b: 2, c: 3, d: 4 };
+const D3: &u32 = &42;
+
+#[repr(C)]
+struct Struct {
+ a: u8,
+ // _pad: [mem::MaybeUninit<u8>; 3]
+ b: u32,
+ c: u16,
+ d: u8,
+ // _pad: [mem::MaybeUninit<u8>; 1]
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr
new file mode 100644
index 000000000..032ceb246
--- /dev/null
+++ b/tests/ui/consts/const-eval/ref_to_int_match.32bit.stderr
@@ -0,0 +1,24 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ref_to_int_match.rs:25:27
+ |
+LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
+ | ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error: could not evaluate constant pattern
+ --> $DIR/ref_to_int_match.rs:7:14
+ |
+LL | 10..=BAR => {},
+ | ^^^
+
+error: could not evaluate constant pattern
+ --> $DIR/ref_to_int_match.rs:7:14
+ |
+LL | 10..=BAR => {},
+ | ^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr
new file mode 100644
index 000000000..032ceb246
--- /dev/null
+++ b/tests/ui/consts/const-eval/ref_to_int_match.64bit.stderr
@@ -0,0 +1,24 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ref_to_int_match.rs:25:27
+ |
+LL | const BAR: Int = unsafe { Foo { r: &42 }.f };
+ | ^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error: could not evaluate constant pattern
+ --> $DIR/ref_to_int_match.rs:7:14
+ |
+LL | 10..=BAR => {},
+ | ^^^
+
+error: could not evaluate constant pattern
+ --> $DIR/ref_to_int_match.rs:7:14
+ |
+LL | 10..=BAR => {},
+ | ^^^
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ref_to_int_match.rs b/tests/ui/consts/const-eval/ref_to_int_match.rs
new file mode 100644
index 000000000..70c6e7d94
--- /dev/null
+++ b/tests/ui/consts/const-eval/ref_to_int_match.rs
@@ -0,0 +1,26 @@
+// stderr-per-bitwidth
+
+fn main() {
+ let n: Int = 40;
+ match n {
+ 0..=10 => {},
+ 10..=BAR => {}, //~ ERROR could not evaluate constant pattern
+ //~| ERROR could not evaluate constant pattern
+ _ => {},
+ }
+}
+
+#[repr(C)]
+union Foo {
+ f: Int,
+ r: &'static u32,
+}
+
+#[cfg(target_pointer_width="64")]
+type Int = u64;
+
+#[cfg(target_pointer_width="32")]
+type Int = u32;
+
+const BAR: Int = unsafe { Foo { r: &42 }.f };
+//~^ ERROR constant
diff --git a/tests/ui/consts/const-eval/shift_overflow.rs b/tests/ui/consts/const-eval/shift_overflow.rs
new file mode 100644
index 000000000..e843584b6
--- /dev/null
+++ b/tests/ui/consts/const-eval/shift_overflow.rs
@@ -0,0 +1,9 @@
+enum Foo {
+ // test that we detect overflows for non-u32 discriminants
+ X = 1 << ((u32::MAX as u64) + 1), //~ ERROR E0080
+ Y = 42,
+}
+
+
+fn main() {
+}
diff --git a/tests/ui/consts/const-eval/shift_overflow.stderr b/tests/ui/consts/const-eval/shift_overflow.stderr
new file mode 100644
index 000000000..e8d4076a6
--- /dev/null
+++ b/tests/ui/consts/const-eval/shift_overflow.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/shift_overflow.rs:3:9
+ |
+LL | X = 1 << ((u32::MAX as u64) + 1),
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to shift left by `4294967296_u64`, which would overflow
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/simd/insert_extract.rs b/tests/ui/consts/const-eval/simd/insert_extract.rs
new file mode 100644
index 000000000..3472c05d1
--- /dev/null
+++ b/tests/ui/consts/const-eval/simd/insert_extract.rs
@@ -0,0 +1,70 @@
+// run-pass
+#![feature(repr_simd)]
+#![feature(platform_intrinsics)]
+#![feature(staged_api)]
+#![stable(feature = "foo", since = "1.3.37")]
+#![allow(non_camel_case_types)]
+
+#[repr(simd)] struct i8x1(i8);
+#[repr(simd)] struct u16x2(u16, u16);
+// Make some of them array types to ensure those also work.
+#[repr(simd)] struct i8x1_arr([i8; 1]);
+#[repr(simd)] struct f32x4([f32; 4]);
+
+extern "platform-intrinsic" {
+ #[rustc_const_stable(feature = "foo", since = "1.3.37")]
+ fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
+ #[rustc_const_stable(feature = "foo", since = "1.3.37")]
+ fn simd_extract<T, U>(x: T, idx: u32) -> U;
+}
+
+fn main() {
+ {
+ const U: i8x1 = i8x1(13);
+ const V: i8x1 = unsafe { simd_insert(U, 0_u32, 42_i8) };
+ const X0: i8 = V.0;
+ const Y0: i8 = unsafe { simd_extract(V, 0) };
+ assert_eq!(X0, 42);
+ assert_eq!(Y0, 42);
+ }
+ {
+ const U: i8x1_arr = i8x1_arr([13]);
+ const V: i8x1_arr = unsafe { simd_insert(U, 0_u32, 42_i8) };
+ const X0: i8 = V.0[0];
+ const Y0: i8 = unsafe { simd_extract(V, 0) };
+ assert_eq!(X0, 42);
+ assert_eq!(Y0, 42);
+ }
+ {
+ const U: u16x2 = u16x2(13, 14);
+ const V: u16x2 = unsafe { simd_insert(U, 1_u32, 42_u16) };
+ const X0: u16 = V.0;
+ const X1: u16 = V.1;
+ const Y0: u16 = unsafe { simd_extract(V, 0) };
+ const Y1: u16 = unsafe { simd_extract(V, 1) };
+ assert_eq!(X0, 13);
+ assert_eq!(X1, 42);
+ assert_eq!(Y0, 13);
+ assert_eq!(Y1, 42);
+ }
+ {
+ const U: f32x4 = f32x4([13., 14., 15., 16.]);
+ const V: f32x4 = unsafe { simd_insert(U, 1_u32, 42_f32) };
+ const X0: f32 = V.0[0];
+ const X1: f32 = V.0[1];
+ const X2: f32 = V.0[2];
+ const X3: f32 = V.0[3];
+ const Y0: f32 = unsafe { simd_extract(V, 0) };
+ const Y1: f32 = unsafe { simd_extract(V, 1) };
+ const Y2: f32 = unsafe { simd_extract(V, 2) };
+ const Y3: f32 = unsafe { simd_extract(V, 3) };
+ assert_eq!(X0, 13.);
+ assert_eq!(X1, 42.);
+ assert_eq!(X2, 15.);
+ assert_eq!(X3, 16.);
+ assert_eq!(Y0, 13.);
+ assert_eq!(Y1, 42.);
+ assert_eq!(Y2, 15.);
+ assert_eq!(Y3, 16.);
+ }
+}
diff --git a/tests/ui/consts/const-eval/simple_with_undef.rs b/tests/ui/consts/const-eval/simple_with_undef.rs
new file mode 100644
index 000000000..1a416dd46
--- /dev/null
+++ b/tests/ui/consts/const-eval/simple_with_undef.rs
@@ -0,0 +1,6 @@
+// check-pass
+
+const PARSE_BOOL: Option<&'static str> = None;
+static FOO: (Option<&str>, u32) = (PARSE_BOOL, 42);
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/size-of-t.rs b/tests/ui/consts/const-eval/size-of-t.rs
new file mode 100644
index 000000000..efbdeec70
--- /dev/null
+++ b/tests/ui/consts/const-eval/size-of-t.rs
@@ -0,0 +1,13 @@
+// https://github.com/rust-lang/rust/issues/69228
+// Used to give bogus suggestion about T not being Sized.
+
+use std::mem::size_of;
+
+fn foo<T>() {
+ let _arr: [u8; size_of::<T>()];
+ //~^ ERROR generic parameters may not be used in const operations
+ //~| NOTE cannot perform const operation
+ //~| NOTE type parameters may not be used in const expressions
+}
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/size-of-t.stderr b/tests/ui/consts/const-eval/size-of-t.stderr
new file mode 100644
index 000000000..abe641046
--- /dev/null
+++ b/tests/ui/consts/const-eval/size-of-t.stderr
@@ -0,0 +1,11 @@
+error: generic parameters may not be used in const operations
+ --> $DIR/size-of-t.rs:7:30
+ |
+LL | let _arr: [u8; size_of::<T>()];
+ | ^ cannot perform const operation using `T`
+ |
+ = note: type parameters may not be used in const expressions
+ = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions
+
+error: aborting due to previous error
+
diff --git a/tests/ui/consts/const-eval/strlen.rs b/tests/ui/consts/const-eval/strlen.rs
new file mode 100644
index 000000000..7b14a5235
--- /dev/null
+++ b/tests/ui/consts/const-eval/strlen.rs
@@ -0,0 +1,31 @@
+// run-pass
+
+const S: &str = "foo";
+pub const B: &[u8] = S.as_bytes();
+pub const C: usize = B.len();
+pub const D: bool = B.is_empty();
+pub const E: bool = S.is_empty();
+pub const F: usize = S.len();
+
+pub fn foo() -> [u8; S.len()] {
+ let mut buf = [0; S.len()];
+ for (i, &c) in S.as_bytes().iter().enumerate() {
+ buf[i] = c;
+ }
+ buf
+}
+
+fn main() {
+ assert_eq!(&foo()[..], b"foo");
+ assert_eq!(foo().len(), S.len());
+ const LEN: usize = S.len();
+ assert_eq!(LEN, S.len());
+ assert_eq!(B, foo());
+ assert_eq!(B, b"foo");
+ assert_eq!(C, 3);
+ assert_eq!(F, 3);
+ assert!(!D);
+ assert!(!E);
+ const EMPTY: bool = "".is_empty();
+ assert!(EMPTY);
+}
diff --git a/tests/ui/consts/const-eval/transmute-const-promotion.rs b/tests/ui/consts/const-eval/transmute-const-promotion.rs
new file mode 100644
index 000000000..1f0240d4b
--- /dev/null
+++ b/tests/ui/consts/const-eval/transmute-const-promotion.rs
@@ -0,0 +1,6 @@
+use std::mem;
+
+fn main() {
+ let x: &'static u32 = unsafe { &mem::transmute(3.0f32) };
+ //~^ ERROR temporary value dropped while borrowed
+}
diff --git a/tests/ui/consts/const-eval/transmute-const-promotion.stderr b/tests/ui/consts/const-eval/transmute-const-promotion.stderr
new file mode 100644
index 000000000..434a957f6
--- /dev/null
+++ b/tests/ui/consts/const-eval/transmute-const-promotion.stderr
@@ -0,0 +1,14 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/transmute-const-promotion.rs:4:37
+ |
+LL | let x: &'static u32 = unsafe { &mem::transmute(3.0f32) };
+ | ------------ ^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
+ | |
+ | type annotation requires that borrow lasts for `'static`
+LL |
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/const-eval/transmute-const.32bit.stderr b/tests/ui/consts/const-eval/transmute-const.32bit.stderr
new file mode 100644
index 000000000..09fd79986
--- /dev/null
+++ b/tests/ui/consts/const-eval/transmute-const.32bit.stderr
@@ -0,0 +1,14 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/transmute-const.rs:4:1
+ |
+LL | static FOO: bool = unsafe { mem::transmute(3u8) };
+ | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 03 │ .
+ }
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/transmute-const.64bit.stderr b/tests/ui/consts/const-eval/transmute-const.64bit.stderr
new file mode 100644
index 000000000..09fd79986
--- /dev/null
+++ b/tests/ui/consts/const-eval/transmute-const.64bit.stderr
@@ -0,0 +1,14 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/transmute-const.rs:4:1
+ |
+LL | static FOO: bool = unsafe { mem::transmute(3u8) };
+ | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 03 │ .
+ }
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/transmute-const.rs b/tests/ui/consts/const-eval/transmute-const.rs
new file mode 100644
index 000000000..d9d0a3aea
--- /dev/null
+++ b/tests/ui/consts/const-eval/transmute-const.rs
@@ -0,0 +1,7 @@
+// stderr-per-bitwidth
+use std::mem;
+
+static FOO: bool = unsafe { mem::transmute(3u8) };
+//~^ ERROR it is undefined behavior to use this value
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ub-enum-overwrite.rs b/tests/ui/consts/const-eval/ub-enum-overwrite.rs
new file mode 100644
index 000000000..086a1001d
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-enum-overwrite.rs
@@ -0,0 +1,18 @@
+#![feature(const_mut_refs)]
+
+enum E {
+ A(u8),
+ B,
+}
+
+const _: u8 = {
+ let mut e = E::A(1);
+ let p = if let E::A(x) = &mut e { x as *mut u8 } else { unreachable!() };
+ // Make sure overwriting `e` uninitializes other bytes
+ e = E::B;
+ unsafe { *p }
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ub-enum-overwrite.stderr b/tests/ui/consts/const-eval/ub-enum-overwrite.stderr
new file mode 100644
index 000000000..5750212b4
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-enum-overwrite.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum-overwrite.rs:13:14
+ |
+LL | unsafe { *p }
+ | ^^ using uninitialized data, but 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/consts/const-eval/ub-enum.32bit.stderr b/tests/ui/consts/const-eval/ub-enum.32bit.stderr
new file mode 100644
index 000000000..2d86bd88f
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-enum.32bit.stderr
@@ -0,0 +1,121 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:27:1
+ |
+LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x00000001, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:30:1
+ |
+LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:33:1
+ |
+LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:45:1
+ |
+LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x00000000, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:47:1
+ |
+LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:50:1
+ |
+LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:59:42
+ |
+LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:64:1
+ |
+LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:81:1
+ |
+LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:83:1
+ |
+LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:91:1
+ |
+LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:96:77
+ |
+LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
+ | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:98:77
+ |
+LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
+ | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+
+error: aborting due to 13 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-enum.64bit.stderr b/tests/ui/consts/const-eval/ub-enum.64bit.stderr
new file mode 100644
index 000000000..a89d7ec5f
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-enum.64bit.stderr
@@ -0,0 +1,121 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:27:1
+ |
+LL | const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x0000000000000001, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:30:1
+ |
+LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:33:1
+ |
+LL | const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:45:1
+ |
+LL | const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-tag>: encountered 0x0000000000000000, but expected a valid enum tag
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:47:1
+ |
+LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:50:1
+ |
+LL | const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:59:42
+ |
+LL | const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:64:1
+ |
+LL | const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:81:1
+ |
+LL | const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(B)>.0: encountered a value of the never type `!`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:83:1
+ |
+LL | const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(D)>.0: encountered a value of uninhabited type Never
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-enum.rs:91:1
+ |
+LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<enum-variant(Some)>.0.1: encountered 0xffffffff, but expected a valid unicode scalar value (in `0..=0x10FFFF` but not in `0xD800..=0xDFFF`)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:96:77
+ |
+LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
+ | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-enum.rs:98:77
+ |
+LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
+ | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+
+error: aborting due to 13 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-enum.rs b/tests/ui/consts/const-eval/ub-enum.rs
new file mode 100644
index 000000000..8f26d9a00
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-enum.rs
@@ -0,0 +1,102 @@
+// stderr-per-bitwidth
+// Strip out raw byte dumps to make comparison platform-independent:
+// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
+// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
+#![feature(never_type)]
+#![allow(invalid_value)]
+
+use std::mem;
+
+#[repr(transparent)]
+#[derive(Copy, Clone)]
+struct Wrap<T>(T);
+
+#[derive(Copy, Clone)]
+enum Never {}
+
+// # simple enum with discriminant 0
+
+#[repr(usize)]
+#[derive(Copy, Clone)]
+enum Enum {
+ A = 0,
+}
+
+const GOOD_ENUM: Enum = unsafe { mem::transmute(0usize) };
+
+const BAD_ENUM: Enum = unsafe { mem::transmute(1usize) };
+//~^ ERROR is undefined behavior
+
+const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) };
+//~^ ERROR evaluation of constant value failed
+
+const BAD_ENUM_WRAPPED: Wrap<Enum> = unsafe { mem::transmute(&1) };
+//~^ ERROR evaluation of constant value failed
+
+// # simple enum with discriminant 2
+
+// (Potentially) invalid enum discriminant
+#[repr(usize)]
+#[derive(Copy, Clone)]
+enum Enum2 {
+ A = 2,
+}
+
+const BAD_ENUM2: Enum2 = unsafe { mem::transmute(0usize) };
+//~^ ERROR is undefined behavior
+const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) };
+//~^ ERROR evaluation of constant value failed
+// something wrapping the enum so that we test layout first, not enum
+const BAD_ENUM2_WRAPPED: Wrap<Enum2> = unsafe { mem::transmute(&0) };
+//~^ ERROR evaluation of constant value failed
+
+// Undef enum discriminant.
+#[repr(C)]
+union MaybeUninit<T: Copy> {
+ uninit: (),
+ init: T,
+}
+const BAD_ENUM2_UNDEF : Enum2 = unsafe { MaybeUninit { uninit: () }.init };
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
+
+// Pointer value in an enum with a niche that is not just 0.
+const BAD_ENUM2_OPTION_PTR: Option<Enum2> = unsafe { mem::transmute(&0) };
+//~^ ERROR evaluation of constant value failed
+
+// # valid discriminant for uninhabited variant
+
+// An enum with 3 variants of which some are uninhabited -- so the uninhabited variants *do*
+// have a discriminant.
+enum UninhDiscriminant {
+ A,
+ B(!),
+ C,
+ D(Never),
+}
+
+const GOOD_INHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(0u8) }; // variant A
+const GOOD_INHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(2u8) }; // variant C
+
+const BAD_UNINHABITED_VARIANT1: UninhDiscriminant = unsafe { mem::transmute(1u8) };
+//~^ ERROR is undefined behavior
+const BAD_UNINHABITED_VARIANT2: UninhDiscriminant = unsafe { mem::transmute(3u8) };
+//~^ ERROR is undefined behavior
+
+// # other
+
+// Invalid enum field content (mostly to test printing of paths for enum tuple
+// variants and tuples).
+// Need to create something which does not clash with enum layout optimizations.
+const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute(!0u32) }));
+//~^ ERROR is undefined behavior
+
+// All variants are uninhabited but also have data.
+// Use `0` as constant to make behavior endianness-independent.
+const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) };
+//~^ ERROR evaluation of constant value failed
+const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) };
+//~^ ERROR evaluation of constant value failed
+
+fn main() {
+}
diff --git a/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr b/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr
new file mode 100644
index 000000000..965256de2
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.32bit.stderr
@@ -0,0 +1,59 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-incorrect-vtable.rs:19:14
+ |
+LL | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-incorrect-vtable.rs:24:14
+ |
+LL | unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:33:1
+ |
+LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:38:1
+ |
+LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:44:1
+ |
+LL | const INVALID_VTABLE_UB: W<&dyn Trait> =
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:91:1
+ |
+LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
+ | ^^^^^^^^^^^^^ constructing invalid value at .1: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾─allocN─╼ ╾─allocN─╼ │ ╾──╼╾──╼
+ }
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr b/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr
new file mode 100644
index 000000000..bd542a7a5
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.64bit.stderr
@@ -0,0 +1,59 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-incorrect-vtable.rs:19:14
+ |
+LL | unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-incorrect-vtable.rs:24:14
+ |
+LL | unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:33:1
+ |
+LL | const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:38:1
+ |
+LL | const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:44:1
+ |
+LL | const INVALID_VTABLE_UB: W<&dyn Trait> =
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-incorrect-vtable.rs:91:1
+ |
+LL | const G: Wide = unsafe { Transmute { t: FOO }.u };
+ | ^^^^^^^^^^^^^ constructing invalid value at .1: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾───────allocN───────╼ ╾───────allocN───────╼ │ ╾──────╼╾──────╼
+ }
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-incorrect-vtable.rs b/tests/ui/consts/const-eval/ub-incorrect-vtable.rs
new file mode 100644
index 000000000..4bb30b75b
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-incorrect-vtable.rs
@@ -0,0 +1,96 @@
+// This test contains code with incorrect vtables in a const context:
+// - from issue 86132: a trait object with invalid alignment caused an ICE in const eval, and now
+// triggers an error
+// - a similar test that triggers a previously-untested const UB error: emitted close to the above
+// error, it checks the correctness of the size
+//
+// As is, this code will only hard error when the constants are used, and the errors are emitted via
+// the `#[allow]`-able `const_err` lint. However, if the transparent wrapper technique to prevent
+// reborrows is used -- from `ub-wide-ptr.rs` -- these two errors reach validation and would trigger
+// ICEs as tracked by #86193. So we also use the transparent wrapper to verify proper validation
+// errors are emitted instead of ICEs.
+
+// stderr-per-bitwidth
+// normalize-stderr-test "alloc\d+" -> "allocN"
+
+trait Trait {}
+
+const INVALID_VTABLE_ALIGNMENT: &dyn Trait =
+ unsafe { std::mem::transmute((&92u8, &[0usize, 1usize, 1000usize])) };
+//~^ ERROR evaluation of constant value failed
+//~| does not point to a vtable
+
+const INVALID_VTABLE_SIZE: &dyn Trait =
+ unsafe { std::mem::transmute((&92u8, &[1usize, usize::MAX, 1usize])) };
+//~^ ERROR evaluation of constant value failed
+//~| does not point to a vtable
+
+#[repr(transparent)]
+struct W<T>(T);
+
+fn drop_me(_: *mut usize) {}
+
+const INVALID_VTABLE_ALIGNMENT_UB: W<&dyn Trait> =
+ unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), 1usize, 1000usize))) };
+//~^^ ERROR it is undefined behavior to use this value
+//~| expected a vtable pointer
+
+const INVALID_VTABLE_SIZE_UB: W<&dyn Trait> =
+ unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), usize::MAX, 1usize))) };
+//~^^ ERROR it is undefined behavior to use this value
+//~| expected a vtable pointer
+
+// Even if the vtable has a fn ptr and a reasonable size+align, it still does not work.
+const INVALID_VTABLE_UB: W<&dyn Trait> =
+ unsafe { std::mem::transmute((&92u8, &(drop_me as fn(*mut usize), 1usize, 1usize))) };
+//~^^ ERROR it is undefined behavior to use this value
+//~| expected a vtable pointer
+
+// Trying to access the data in a vtable does not work, either.
+
+#[derive(Copy, Clone)]
+struct Wide<'a>(&'a Foo, &'static VTable);
+
+struct VTable {
+ drop: Option<for<'a> fn(&'a mut Foo)>,
+ size: usize,
+ align: usize,
+ bar: for<'a> fn(&'a Foo) -> u32,
+}
+
+trait Bar {
+ fn bar(&self) -> u32;
+}
+
+struct Foo {
+ foo: u32,
+ bar: bool,
+}
+
+impl Bar for Foo {
+ fn bar(&self) -> u32 {
+ self.foo
+ }
+}
+
+impl Drop for Foo {
+ fn drop(&mut self) {
+ assert!(!self.bar);
+ self.bar = true;
+ println!("dropping Foo");
+ }
+}
+
+#[repr(C)]
+union Transmute<T: Copy, U: Copy> {
+ t: T,
+ u: U,
+}
+
+const FOO: &dyn Bar = &Foo { foo: 128, bar: false };
+const G: Wide = unsafe { Transmute { t: FOO }.u };
+//~^ ERROR it is undefined behavior to use this value
+//~| encountered a dangling reference
+// (it is dangling because vtables do not contain memory that can be dereferenced)
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ub-int-array.32bit.stderr b/tests/ui/consts/const-eval/ub-int-array.32bit.stderr
new file mode 100644
index 000000000..edcde13b0
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-int-array.32bit.stderr
@@ -0,0 +1,21 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:15:9
+ |
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:30:13
+ |
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:56:13
+ |
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-int-array.64bit.stderr b/tests/ui/consts/const-eval/ub-int-array.64bit.stderr
new file mode 100644
index 000000000..edcde13b0
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-int-array.64bit.stderr
@@ -0,0 +1,21 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:15:9
+ |
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:30:13
+ |
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-int-array.rs:56:13
+ |
+LL | MaybeUninit { uninit: () }.init,
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-int-array.rs b/tests/ui/consts/const-eval/ub-int-array.rs
new file mode 100644
index 000000000..a68d3fb17
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-int-array.rs
@@ -0,0 +1,63 @@
+// stderr-per-bitwidth
+//! Test the "array of int" fast path in validity checking, and in particular whether it
+//! points at the right array element.
+
+use std::mem;
+
+#[repr(C)]
+union MaybeUninit<T: Copy> {
+ uninit: (),
+ init: T,
+}
+
+const UNINIT_INT_0: [u32; 3] = unsafe {
+ [
+ MaybeUninit { uninit: () }.init,
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
+ 1,
+ 2,
+ ]
+};
+const UNINIT_INT_1: [u32; 3] = unsafe {
+ mem::transmute(
+ [
+ 0u8,
+ 0u8,
+ 0u8,
+ 0u8,
+ 1u8,
+ MaybeUninit { uninit: () }.init,
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
+ 1u8,
+ 1u8,
+ 2u8,
+ 2u8,
+ MaybeUninit { uninit: () }.init,
+ 2u8,
+ ]
+ )
+};
+const UNINIT_INT_2: [u32; 3] = unsafe {
+ mem::transmute(
+ [
+ 0u8,
+ 0u8,
+ 0u8,
+ 0u8,
+ 1u8,
+ 1u8,
+ 1u8,
+ 1u8,
+ 2u8,
+ 2u8,
+ 2u8,
+ MaybeUninit { uninit: () }.init,
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
+ ]
+ )
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr b/tests/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr
new file mode 100644
index 000000000..2a4b6f3b7
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-nonnull.chalk.64bit.stderr
@@ -0,0 +1,9 @@
+error[E0284]: type annotations needed: cannot satisfy `<usize as SliceIndex<[u8]>>::Output == _`
+ --> $DIR/ub-nonnull.rs:19:30
+ |
+LL | let out_of_bounds_ptr = &ptr[255];
+ | ^^^^^^^^ cannot satisfy `<usize as SliceIndex<[u8]>>::Output == _`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/consts/const-eval/ub-nonnull.rs b/tests/ui/consts/const-eval/ub-nonnull.rs
new file mode 100644
index 000000000..a64b3a74c
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-nonnull.rs
@@ -0,0 +1,59 @@
+// Strip out raw byte dumps to make comparison platform-independent:
+// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
+// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
+#![feature(rustc_attrs, ptr_metadata)]
+#![allow(invalid_value)] // make sure we cannot allow away the errors tested here
+
+use std::mem;
+use std::ptr::NonNull;
+use std::num::{NonZeroU8, NonZeroUsize};
+
+const NON_NULL: NonNull<u8> = unsafe { mem::transmute(1usize) };
+const NON_NULL_PTR: NonNull<u8> = unsafe { mem::transmute(&1) };
+
+const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
+ let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
+ // Use address-of-element for pointer arithmetic. This could wrap around to null!
+ let out_of_bounds_ptr = &ptr[255]; //~ ERROR evaluation of constant value failed
+ mem::transmute(out_of_bounds_ptr)
+} };
+
+const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
+//~^ ERROR it is undefined behavior to use this value
+const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+#[repr(C)]
+union MaybeUninit<T: Copy> {
+ uninit: (),
+ init: T,
+}
+const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
+
+// Also test other uses of rustc_layout_scalar_valid_range_start
+
+#[rustc_layout_scalar_valid_range_start(10)]
+#[rustc_layout_scalar_valid_range_end(30)]
+struct RestrictedRange1(u32);
+const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
+//~^ ERROR it is undefined behavior to use this value
+
+#[rustc_layout_scalar_valid_range_start(30)]
+#[rustc_layout_scalar_valid_range_end(10)]
+struct RestrictedRange2(u32);
+const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
+//~^ ERROR it is undefined behavior to use this value
+
+const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
+//~^ ERROR it is undefined behavior to use this value
+ let x: &dyn Send = &42;
+ let meta = std::ptr::metadata(x);
+ mem::transmute((0_usize, meta))
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ub-nonnull.stderr b/tests/ui/consts/const-eval/ub-nonnull.stderr
new file mode 100644
index 000000000..961648708
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-nonnull.stderr
@@ -0,0 +1,81 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:14:1
+ |
+LL | const NULL_PTR: NonNull<u8> = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-nonnull.rs:20:30
+ |
+LL | let out_of_bounds_ptr = &ptr[255];
+ | ^^^^^^^^ dereferencing pointer failed: alloc11 has size 1, so pointer to 256 bytes starting at offset 0 is out-of-bounds
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:24:1
+ |
+LL | const NULL_U8: NonZeroU8 = unsafe { mem::transmute(0u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:26:1
+ |
+LL | const NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-nonnull.rs:34:36
+ |
+LL | const UNINIT: NonZeroU8 = unsafe { MaybeUninit { uninit: () }.init };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:43:1
+ |
+LL | const BAD_RANGE1: RestrictedRange1 = unsafe { RestrictedRange1(42) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 42, but expected something in the range 10..=30
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:49:1
+ |
+LL | const BAD_RANGE2: RestrictedRange2 = unsafe { RestrictedRange2(20) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 20, but expected something less or equal to 10, or greater or equal to 30
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-nonnull.rs:52:1
+ |
+LL | const NULL_FAT_PTR: NonNull<dyn Send> = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0, but expected something greater or equal to 1
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error: aborting due to 8 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.rs b/tests/ui/consts/const-eval/ub-ref-ptr.rs
new file mode 100644
index 000000000..369e45194
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-ref-ptr.rs
@@ -0,0 +1,71 @@
+// ignore-tidy-linelength
+// Strip out raw byte dumps to make comparison platform-independent:
+// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
+// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
+#![allow(invalid_value)]
+#![feature(const_ptr_read)]
+
+use std::mem;
+
+#[repr(C)]
+union MaybeUninit<T: Copy> {
+ uninit: (),
+ init: T,
+}
+
+const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
+//~^ ERROR it is undefined behavior to use this value
+//~| constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1)
+
+const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
+//~^ ERROR it is undefined behavior to use this value
+//~| constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1)
+
+const NULL: &u16 = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+
+// It is very important that we reject this: We do promote `&(4 * REF_AS_USIZE)`,
+// but that would fail to compile; so we ended up breaking user code that would
+// have worked fine had we not promoted.
+const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
+//~^ ERROR evaluation of constant value failed
+
+const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
+//~^ ERROR evaluation of constant value failed
+
+const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
+//~^ ERROR evaluation of constant value failed
+
+const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
+
+const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
+//~^ ERROR it is undefined behavior to use this value
+const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
+const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
+//~^ ERROR it is undefined behavior to use this value
+const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
+//~^ ERROR it is undefined behavior to use this value
+
+
+const UNALIGNED_READ: () = unsafe {
+ let x = &[0u8; 4];
+ let ptr = x.as_ptr().cast::<u32>();
+ ptr.read(); //~ inside `UNALIGNED_READ`
+};
+
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ub-ref-ptr.stderr b/tests/ui/consts/const-eval/ub-ref-ptr.stderr
new file mode 100644
index 000000000..ce618802b
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-ref-ptr.stderr
@@ -0,0 +1,186 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-ref-ptr.rs:16:1
+ |
+LL | const UNALIGNED: &u16 = unsafe { mem::transmute(&[0u8; 4]) };
+ | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required 2 byte alignment but found 1)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-ref-ptr.rs:20:1
+ |
+LL | const UNALIGNED_BOX: Box<u16> = unsafe { mem::transmute(&[0u8; 4]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned box (required 2 byte alignment but found 1)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-ref-ptr.rs:24:1
+ |
+LL | const NULL: &u16 = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null reference
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-ref-ptr.rs:27:1
+ |
+LL | const NULL_BOX: Box<u16> = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a null box
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-ref-ptr.rs:34:1
+ |
+LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-ref-ptr.rs:37:39
+ |
+LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+note: erroneous constant used
+ --> $DIR/ub-ref-ptr.rs:37:38
+ |
+LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-ref-ptr.rs:40:86
+ |
+LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
+ | ^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+note: erroneous constant used
+ --> $DIR/ub-ref-ptr.rs:40:85
+ |
+LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) };
+ | ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-ref-ptr.rs:43:1
+ |
+LL | const USIZE_AS_REF: &'static u8 = unsafe { mem::transmute(1337usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (address 0x539 is unallocated)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-ref-ptr.rs:46:1
+ |
+LL | const USIZE_AS_BOX: Box<u8> = unsafe { mem::transmute(1337usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (address 0x539 is unallocated)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-ref-ptr.rs:49:41
+ |
+LL | const UNINIT_PTR: *const i32 = unsafe { MaybeUninit { uninit: () }.init };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-ref-ptr.rs:53:1
+ |
+LL | const NULL_FN_PTR: fn() = unsafe { mem::transmute(0usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a function pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-ref-ptr.rs:55:38
+ |
+LL | const UNINIT_FN_PTR: fn() = unsafe { MaybeUninit { uninit: () }.init };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-ref-ptr.rs:58:1
+ |
+LL | const DANGLING_FN_PTR: fn() = unsafe { mem::transmute(13usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0xd[noalloc], but expected a function pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-ref-ptr.rs:60:1
+ |
+LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered alloc41, but expected a function pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error: accessing memory with alignment 1, but alignment 4 is required
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/104616>
+note: inside `std::ptr::read::<u32>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::read`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+note: inside `UNALIGNED_READ`
+ --> $DIR/ub-ref-ptr.rs:67:5
+ |
+LL | ptr.read();
+ | ^^^^^^^^^^
+ = note: `#[deny(invalid_alignment)]` on by default
+
+error: aborting due to 15 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
+Future incompatibility report: Future breakage diagnostic:
+error: accessing memory with alignment 1, but alignment 4 is required
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+ |
+ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+ = note: for more information, see issue #68585 <https://github.com/rust-lang/rust/issues/104616>
+note: inside `std::ptr::read::<u32>`
+ --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL
+note: inside `ptr::const_ptr::<impl *const u32>::read`
+ --> $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL
+note: inside `UNALIGNED_READ`
+ --> $DIR/ub-ref-ptr.rs:67:5
+ |
+LL | ptr.read();
+ | ^^^^^^^^^^
+ = note: `#[deny(invalid_alignment)]` on by default
+
diff --git a/tests/ui/consts/const-eval/ub-uninhabit.rs b/tests/ui/consts/const-eval/ub-uninhabit.rs
new file mode 100644
index 000000000..4c4ef216d
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-uninhabit.rs
@@ -0,0 +1,25 @@
+// Strip out raw byte dumps to make comparison platform-independent:
+// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
+// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
+
+use std::mem;
+
+#[derive(Copy, Clone)]
+enum Bar {}
+
+#[repr(C)]
+union MaybeUninit<T: Copy> {
+ uninit: (),
+ init: T,
+}
+
+const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init };
+//~^ ERROR it is undefined behavior to use this value
+
+const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
+//~^ ERROR it is undefined behavior to use this value
+
+const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init };
+//~^ ERROR it is undefined behavior to use this value
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ub-uninhabit.stderr b/tests/ui/consts/const-eval/ub-uninhabit.stderr
new file mode 100644
index 000000000..0ae376d03
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-uninhabit.stderr
@@ -0,0 +1,32 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-uninhabit.rs:16:1
+ |
+LL | const BAD_BAD_BAD: Bar = unsafe { MaybeUninit { uninit: () }.init };
+ | ^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a value of uninhabited type Bar
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {}
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-uninhabit.rs:19:1
+ |
+LL | const BAD_BAD_REF: &Bar = unsafe { mem::transmute(1usize) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a reference pointing to uninhabited type Bar
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-uninhabit.rs:22:1
+ |
+LL | const BAD_BAD_ARRAY: [Bar; 1] = unsafe { MaybeUninit { uninit: () }.init };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered a value of uninhabited type Bar
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {}
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-upvars.32bit.stderr b/tests/ui/consts/const-eval/ub-upvars.32bit.stderr
new file mode 100644
index 000000000..f7898e55e
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-upvars.32bit.stderr
@@ -0,0 +1,14 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-upvars.rs:6:1
+ |
+LL | const BAD_UPVAR: &dyn FnOnce() = &{
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>.<captured-var(bad_ref)>: encountered a null reference
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 8, align: 4) {
+ ╾─alloc3──╼ ╾─alloc4──╼ │ ╾──╼╾──╼
+ }
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-upvars.64bit.stderr b/tests/ui/consts/const-eval/ub-upvars.64bit.stderr
new file mode 100644
index 000000000..60432380e
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-upvars.64bit.stderr
@@ -0,0 +1,14 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-upvars.rs:6:1
+ |
+LL | const BAD_UPVAR: &dyn FnOnce() = &{
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>.<captured-var(bad_ref)>: encountered a null reference
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 16, align: 8) {
+ ╾───────alloc3────────╼ ╾───────alloc4────────╼ │ ╾──────╼╾──────╼
+ }
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/ub-upvars.rs b/tests/ui/consts/const-eval/ub-upvars.rs
new file mode 100644
index 000000000..ceac59870
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-upvars.rs
@@ -0,0 +1,12 @@
+// stderr-per-bitwidth
+#![allow(invalid_value)] // make sure we cannot allow away the errors tested here
+
+use std::mem;
+
+const BAD_UPVAR: &dyn FnOnce() = &{ //~ ERROR it is undefined behavior to use this value
+ let bad_ref: &'static u16 = unsafe { mem::transmute(0usize) };
+ let another_var = 13;
+ move || { let _ = bad_ref; let _ = another_var; }
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr
new file mode 100644
index 000000000..39352ca84
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-wide-ptr.chalk.64bit.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+ --> $DIR/ub-wide-ptr.rs:90:67
+ |
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+ | ^^^^^^^^^^^^^^ cannot infer type for type parameter `U` declared on the function `transmute`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.rs b/tests/ui/consts/const-eval/ub-wide-ptr.rs
new file mode 100644
index 000000000..a765dc712
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-wide-ptr.rs
@@ -0,0 +1,159 @@
+// ignore-tidy-linelength
+#![allow(unused)]
+
+use std::mem;
+
+// Strip out raw byte dumps to make comparison platform-independent:
+// normalize-stderr-test "(the raw bytes of the constant) \(size: [0-9]*, align: [0-9]*\)" -> "$1 (size: $$SIZE, align: $$ALIGN)"
+// normalize-stderr-test "([0-9a-f][0-9a-f] |╾─*a(lloc)?[0-9]+(\+[a-z0-9]+)?─*╼ )+ *│.*" -> "HEX_DUMP"
+// normalize-stderr-test "offset \d+" -> "offset N"
+// normalize-stderr-test "alloc\d+" -> "allocN"
+// normalize-stderr-test "size \d+" -> "size N"
+
+/// A newtype wrapper to prevent MIR generation from inserting reborrows that would affect the error
+/// message.
+#[repr(transparent)]
+struct W<T>(T);
+
+#[repr(C)]
+union MaybeUninit<T: Copy> {
+ uninit: (),
+ init: T,
+}
+
+trait Trait {}
+impl Trait for bool {}
+
+// custom unsized type
+struct MyStr(str);
+
+// custom unsized type with sized fields
+struct MySlice<T: ?Sized>(bool, T);
+type MySliceBool = MySlice<[bool]>;
+
+// # str
+// OK
+const STR_VALID: &str = unsafe { mem::transmute((&42u8, 1usize)) };
+// bad str
+const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
+//~^ ERROR it is undefined behavior to use this value
+const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
+//~^ ERROR it is undefined behavior to use this value
+// bad str
+const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
+//~^ ERROR evaluation of constant value failed
+// bad str in user-defined unsized type
+const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
+//~^ ERROR evaluation of constant value failed
+const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
+//~^ ERROR it is undefined behavior to use this value
+
+// uninitialized byte
+const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+//~^ ERROR it is undefined behavior to use this value
+// uninitialized byte in user-defined str-like
+const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+//~^ ERROR it is undefined behavior to use this value
+
+// # slice
+// OK
+const SLICE_VALID: &[u8] = unsafe { mem::transmute((&42u8, 1usize)) };
+// bad slice: length uninit
+const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
+ let uninit_len = MaybeUninit::<usize> { uninit: () };
+ mem::transmute((42, uninit_len))
+};
+// bad slice: length too big
+const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
+//~^ ERROR it is undefined behavior to use this value
+// bad slice: length computation overflows
+const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
+//~^ ERROR it is undefined behavior to use this value
+// bad slice: length not an int
+const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
+//~^ ERROR evaluation of constant value failed
+// bad slice box: length too big
+const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
+//~^ ERROR it is undefined behavior to use this value
+// bad slice box: length not an int
+const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
+//~^ ERROR evaluation of constant value failed
+
+// bad data *inside* the slice
+const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+//~^ ERROR it is undefined behavior to use this value
+//~| constant
+
+// good MySliceBool
+const MYSLICE_GOOD: &MySliceBool = &MySlice(true, [false]);
+// bad: sized field is not okay
+const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+//~^ ERROR it is undefined behavior to use this value
+//~| constant
+// bad: unsized part is not okay
+const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+//~^ ERROR it is undefined behavior to use this value
+//~| constant
+
+// # raw slice
+const RAW_SLICE_VALID: *const [u8] = unsafe { mem::transmute((&42u8, 1usize)) }; // ok
+const RAW_SLICE_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, 999usize)) }; // ok because raw
+const RAW_SLICE_MUCH_TOO_LONG: *const [u8] = unsafe { mem::transmute((&42u8, usize::MAX)) }; // ok because raw
+const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
+ let uninit_len = MaybeUninit::<usize> { uninit: () };
+ mem::transmute((42, uninit_len))
+};
+
+// # trait object
+// bad trait object
+const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a vtable
+// bad trait object
+const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a vtable
+// bad trait object
+const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a vtable
+const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
+//~^ ERROR evaluation of constant value failed
+//~| does not point to a vtable
+const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
+//~^ ERROR evaluation of constant value failed
+//~| does not point to a vtable
+const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
+//~^ ERROR evaluation of constant value failed
+//~| does not point to a vtable
+const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a vtable
+
+// bad data *inside* the trait object
+const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
+//~^ ERROR it is undefined behavior to use this value
+//~| expected a boolean
+
+// # raw trait object
+const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
+//~^ ERROR it is undefined behavior to use this value
+const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
+//~^ ERROR it is undefined behavior to use this value
+const RAW_TRAIT_OBJ_CONTENT_INVALID: *const dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) } as *const dyn Trait; // ok because raw
+
+// Const eval fails for these, so they need to be statics to error.
+static mut RAW_TRAIT_OBJ_VTABLE_NULL_THROUGH_REF: *const dyn Trait = unsafe {
+ mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
+ //~^ ERROR could not evaluate static initializer
+};
+static mut RAW_TRAIT_OBJ_VTABLE_INVALID_THROUGH_REF: *const dyn Trait = unsafe {
+ mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
+ //~^ ERROR could not evaluate static initializer
+};
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.stderr
new file mode 100644
index 000000000..f38e7916b
--- /dev/null
+++ b/tests/ui/consts/const-eval/ub-wide-ptr.stderr
@@ -0,0 +1,297 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:38:1
+ |
+LL | const STR_TOO_LONG: &str = unsafe { mem::transmute((&42u8, 999usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:40:1
+ |
+LL | const NESTED_STR_MUCH_TOO_LONG: (&str,) = (unsafe { mem::transmute((&42, usize::MAX)) },);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered invalid reference metadata: slice is bigger than largest supported object
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:43:1
+ |
+LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:46:1
+ |
+LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:48:1
+ |
+LL | const MY_STR_MUCH_TOO_LONG: &MyStr = unsafe { mem::transmute((&42u8, usize::MAX)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:52:1
+ |
+LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>: encountered uninitialized data in `str`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:55:1
+ |
+LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit::<u8> { uninit: () }]) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered uninitialized data in `str`
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:62:1
+ |
+LL | const SLICE_LENGTH_UNINIT: &[u8] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:69:1
+ |
+LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:72:1
+ |
+LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered invalid reference metadata: slice is bigger than largest supported object
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:75:1
+ |
+LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:78:1
+ |
+LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (going beyond the bounds of its allocation)
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:81:1
+ |
+LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes
+ |
+ = help: this code performed an operation that depends on the underlying bytes representing a pointer
+ = help: the absolute address of a pointer is not known at compile-time, so such operations are not supported
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:85:1
+ |
+LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>[0]: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+note: erroneous constant used
+ --> $DIR/ub-wide-ptr.rs:85:40
+ |
+LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:92:1
+ |
+LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.0: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+note: erroneous constant used
+ --> $DIR/ub-wide-ptr.rs:92:42
+ |
+LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:96:1
+ |
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.1[0]: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+note: erroneous constant used
+ --> $DIR/ub-wide-ptr.rs:96:42
+ |
+LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:104:1
+ |
+LL | const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:113:1
+ |
+LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:117:1
+ |
+LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:121:1
+ |
+LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered 0x4[noalloc], but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:124:57
+ |
+LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:127:57
+ |
+LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/ub-wide-ptr.rs:130:56
+ |
+LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:133:1
+ |
+LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .0: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:138:1
+ |
+LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:143:1
+ |
+LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered null pointer, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/ub-wide-ptr.rs:145:1
+ |
+LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered allocN, but expected a vtable pointer
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) {
+ HEX_DUMP
+ }
+
+error[E0080]: could not evaluate static initializer
+ --> $DIR/ub-wide-ptr.rs:151:5
+ |
+LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: null pointer is a dangling pointer (it has no provenance)
+
+error[E0080]: could not evaluate static initializer
+ --> $DIR/ub-wide-ptr.rs:155:5
+ |
+LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using allocN as vtable pointer but it does not point to a vtable
+
+error: aborting due to 29 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/union-const-eval-field.rs b/tests/ui/consts/const-eval/union-const-eval-field.rs
new file mode 100644
index 000000000..a94fcbbfa
--- /dev/null
+++ b/tests/ui/consts/const-eval/union-const-eval-field.rs
@@ -0,0 +1,38 @@
+// only-x86_64
+
+type Field1 = i32;
+type Field2 = f32;
+type Field3 = i64;
+
+#[repr(C)]
+union DummyUnion {
+ field1: Field1,
+ field2: Field2,
+ field3: Field3,
+}
+
+const FLOAT1_AS_I32: i32 = 1065353216;
+const UNION: DummyUnion = DummyUnion { field1: FLOAT1_AS_I32 };
+
+const fn read_field1() -> Field1 {
+ const FIELD1: Field1 = unsafe { UNION.field1 };
+ FIELD1
+}
+
+const fn read_field2() -> Field2 {
+ const FIELD2: Field2 = unsafe { UNION.field2 };
+ FIELD2
+}
+
+const fn read_field3() -> Field3 {
+ const FIELD3: Field3 = unsafe { UNION.field3 };
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
+ FIELD3
+}
+
+fn main() {
+ assert_eq!(read_field1(), FLOAT1_AS_I32);
+ assert_eq!(read_field2(), 1.0);
+ assert_eq!(read_field3(), unsafe { UNION.field3 });
+}
diff --git a/tests/ui/consts/const-eval/union-const-eval-field.stderr b/tests/ui/consts/const-eval/union-const-eval-field.stderr
new file mode 100644
index 000000000..9899c56c0
--- /dev/null
+++ b/tests/ui/consts/const-eval/union-const-eval-field.stderr
@@ -0,0 +1,21 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-const-eval-field.rs:28:37
+ |
+LL | const FIELD3: Field3 = unsafe { UNION.field3 };
+ | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+note: erroneous constant used
+ --> $DIR/union-const-eval-field.rs:31:5
+ |
+LL | FIELD3
+ | ^^^^^^
+
+note: erroneous constant used
+ --> $DIR/union-const-eval-field.rs:31:5
+ |
+LL | FIELD3
+ | ^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/union-ice.rs b/tests/ui/consts/const-eval/union-ice.rs
new file mode 100644
index 000000000..dd970a355
--- /dev/null
+++ b/tests/ui/consts/const-eval/union-ice.rs
@@ -0,0 +1,48 @@
+// only-x86_64
+
+type Field1 = i32;
+type Field3 = i64;
+
+#[repr(C)]
+union DummyUnion {
+ field1: Field1,
+ field3: Field3,
+}
+
+const UNION: DummyUnion = DummyUnion { field1: 1065353216 };
+
+const FIELD3: Field3 = unsafe { UNION.field3 };
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
+
+const FIELD_PATH: Struct = Struct {
+ a: 42,
+ b: unsafe { UNION.field3 },
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
+};
+
+struct Struct {
+ a: u8,
+ b: Field3,
+}
+
+const FIELD_PATH2: Struct2 = Struct2 {
+ b: [
+ 21,
+ unsafe { UNION.field3 },
+ //~^ ERROR evaluation of constant value failed
+ //~| uninitialized
+ 23,
+ 24,
+ ],
+ a: 42,
+};
+
+struct Struct2 {
+ b: [Field3; 4],
+ a: u8,
+}
+
+fn main() {
+}
diff --git a/tests/ui/consts/const-eval/union-ice.stderr b/tests/ui/consts/const-eval/union-ice.stderr
new file mode 100644
index 000000000..bd39a0551
--- /dev/null
+++ b/tests/ui/consts/const-eval/union-ice.stderr
@@ -0,0 +1,21 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ice.rs:14:33
+ |
+LL | const FIELD3: Field3 = unsafe { UNION.field3 };
+ | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ice.rs:20:17
+ |
+LL | b: unsafe { UNION.field3 },
+ | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ice.rs:33:18
+ |
+LL | unsafe { UNION.field3 },
+ | ^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/union-ub.32bit.stderr b/tests/ui/consts/const-eval/union-ub.32bit.stderr
new file mode 100644
index 000000000..e5c8f88be
--- /dev/null
+++ b/tests/ui/consts/const-eval/union-ub.32bit.stderr
@@ -0,0 +1,20 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/union-ub.rs:32:1
+ |
+LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x2a, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 2a │ *
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ub.rs:34:36
+ |
+LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/union-ub.64bit.stderr b/tests/ui/consts/const-eval/union-ub.64bit.stderr
new file mode 100644
index 000000000..e5c8f88be
--- /dev/null
+++ b/tests/ui/consts/const-eval/union-ub.64bit.stderr
@@ -0,0 +1,20 @@
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/union-ub.rs:32:1
+ |
+LL | const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
+ | ^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x2a, but expected a boolean
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 1, align: 1) {
+ 2a │ *
+ }
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/union-ub.rs:34:36
+ |
+LL | const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/union-ub.rs b/tests/ui/consts/const-eval/union-ub.rs
new file mode 100644
index 000000000..043870c9c
--- /dev/null
+++ b/tests/ui/consts/const-eval/union-ub.rs
@@ -0,0 +1,43 @@
+// stderr-per-bitwidth
+
+#[repr(C)]
+union DummyUnion {
+ unit: (),
+ u8: u8,
+ bool: bool,
+}
+
+#[repr(C)]
+#[derive(Copy, Clone)]
+enum Enum {
+ A,
+ B,
+ C,
+}
+
+#[derive(Copy, Clone)]
+#[repr(C)]
+union Foo {
+ a: bool,
+ b: Enum,
+}
+
+#[repr(C)]
+union Bar {
+ foo: Foo,
+ u8: u8,
+}
+
+// the value is not valid for bools
+const BAD_BOOL: bool = unsafe { DummyUnion { u8: 42 }.bool};
+//~^ ERROR it is undefined behavior to use this value
+const UNINIT_BOOL: bool = unsafe { DummyUnion { unit: () }.bool};
+//~^ ERROR evaluation of constant value failed
+//~| uninitialized
+
+// The value is not valid for any union variant, but that's fine
+// unions are just a convenient way to transmute bits around
+const BAD_UNION: Foo = unsafe { Bar { u8: 42 }.foo };
+
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/union_promotion.rs b/tests/ui/consts/const-eval/union_promotion.rs
new file mode 100644
index 000000000..18894c45f
--- /dev/null
+++ b/tests/ui/consts/const-eval/union_promotion.rs
@@ -0,0 +1,11 @@
+#[repr(C)]
+union Foo {
+ a: &'static u32,
+ b: usize,
+}
+
+fn main() {
+ let x: &'static bool = &unsafe { //~ temporary value dropped while borrowed
+ Foo { a: &1 }.b == Foo { a: &2 }.b
+ };
+}
diff --git a/tests/ui/consts/const-eval/union_promotion.stderr b/tests/ui/consts/const-eval/union_promotion.stderr
new file mode 100644
index 000000000..42f17de20
--- /dev/null
+++ b/tests/ui/consts/const-eval/union_promotion.stderr
@@ -0,0 +1,16 @@
+error[E0716]: temporary value dropped while borrowed
+ --> $DIR/union_promotion.rs:8:29
+ |
+LL | let x: &'static bool = &unsafe {
+ | ____________-------------____^
+ | | |
+ | | type annotation requires that borrow lasts for `'static`
+LL | | Foo { a: &1 }.b == Foo { a: &2 }.b
+LL | | };
+ | |_____^ creates a temporary value which is freed while still in use
+LL | }
+ | - temporary value is freed at the end of this statement
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/const-eval/unused-broken-const.rs b/tests/ui/consts/const-eval/unused-broken-const.rs
new file mode 100644
index 000000000..0d2776bc2
--- /dev/null
+++ b/tests/ui/consts/const-eval/unused-broken-const.rs
@@ -0,0 +1,8 @@
+// make sure that an *unused* broken const triggers an error even in a check build
+
+// compile-flags: --emit=dep-info,metadata
+
+const FOO: i32 = [][0];
+//~^ ERROR evaluation of constant value failed
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/unused-broken-const.stderr b/tests/ui/consts/const-eval/unused-broken-const.stderr
new file mode 100644
index 000000000..fbb10feb7
--- /dev/null
+++ b/tests/ui/consts/const-eval/unused-broken-const.stderr
@@ -0,0 +1,9 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/unused-broken-const.rs:5:18
+ |
+LL | const FOO: i32 = [][0];
+ | ^^^^^ index out of bounds: the length is 0 but the index is 0
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/unwind-abort.rs b/tests/ui/consts/const-eval/unwind-abort.rs
new file mode 100644
index 000000000..2b0e58166
--- /dev/null
+++ b/tests/ui/consts/const-eval/unwind-abort.rs
@@ -0,0 +1,12 @@
+#![feature(c_unwind, const_extern_fn)]
+
+const extern "C" fn foo() {
+ panic!() //~ ERROR evaluation of constant value failed
+}
+
+const _: () = foo();
+// Ensure that the CTFE engine handles calls to `extern "C"` aborting gracefully
+
+fn main() {
+ let _ = foo();
+}
diff --git a/tests/ui/consts/const-eval/unwind-abort.stderr b/tests/ui/consts/const-eval/unwind-abort.stderr
new file mode 100644
index 000000000..759ce15ab
--- /dev/null
+++ b/tests/ui/consts/const-eval/unwind-abort.stderr
@@ -0,0 +1,21 @@
+error[E0080]: evaluation of constant value failed
+ --> $DIR/unwind-abort.rs:4:5
+ |
+LL | panic!()
+ | ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/unwind-abort.rs:4:5
+ |
+note: inside `foo`
+ --> $DIR/unwind-abort.rs:4:5
+ |
+LL | panic!()
+ | ^^^^^^^^
+note: inside `_`
+ --> $DIR/unwind-abort.rs:7:15
+ |
+LL | const _: () = foo();
+ | ^^^^^
+ = note: this error originates in the macro `$crate::panic::panic_2015` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/valid-const.rs b/tests/ui/consts/const-eval/valid-const.rs
new file mode 100644
index 000000000..5f47d1c4f
--- /dev/null
+++ b/tests/ui/consts/const-eval/valid-const.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+// Some constants that *are* valid
+
+use std::mem;
+use std::ptr::NonNull;
+use std::num::{NonZeroU8, NonZeroUsize};
+
+const NON_NULL_PTR1: NonNull<u8> = unsafe { mem::transmute(1usize) };
+const NON_NULL_PTR2: NonNull<u8> = unsafe { mem::transmute(&0) };
+
+const NON_NULL_U8: NonZeroU8 = unsafe { mem::transmute(1u8) };
+const NON_NULL_USIZE: NonZeroUsize = unsafe { mem::transmute(1usize) };
+
+const UNIT: () = ();
+
+fn main() {}
diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
new file mode 100644
index 000000000..9710bf476
--- /dev/null
+++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr
@@ -0,0 +1,61 @@
+warning: the type `!` does not permit zero-initialization
+ --> $DIR/validate_uninhabited_zsts.rs:4:14
+ |
+LL | unsafe { std::mem::transmute(()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: the `!` type has no valid value
+ = note: `#[warn(invalid_value)]` on by default
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/validate_uninhabited_zsts.rs:4:14
+ |
+LL | unsafe { std::mem::transmute(()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+ |
+note: inside `foo`
+ --> $DIR/validate_uninhabited_zsts.rs:4:14
+ |
+LL | unsafe { std::mem::transmute(()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `FOO`
+ --> $DIR/validate_uninhabited_zsts.rs:19:33
+ |
+LL | const FOO: [empty::Empty; 3] = [foo(); 3];
+ | ^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/validate_uninhabited_zsts.rs:21:1
+ |
+LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0].0: encountered a value of uninhabited type empty::Void
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 0, align: 1) {}
+
+warning: the type `empty::Empty` does not permit zero-initialization
+ --> $DIR/validate_uninhabited_zsts.rs:21:42
+ |
+LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: in this struct field
+ --> $DIR/validate_uninhabited_zsts.rs:16:22
+ |
+LL | pub struct Empty(Void);
+ | ^^^^
+note: enums with no inhabited variants have no valid value
+ --> $DIR/validate_uninhabited_zsts.rs:13:5
+ |
+LL | enum Void {}
+ | ^^^^^^^^^
+
+error: aborting due to 2 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
new file mode 100644
index 000000000..9710bf476
--- /dev/null
+++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr
@@ -0,0 +1,61 @@
+warning: the type `!` does not permit zero-initialization
+ --> $DIR/validate_uninhabited_zsts.rs:4:14
+ |
+LL | unsafe { std::mem::transmute(()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+ = note: the `!` type has no valid value
+ = note: `#[warn(invalid_value)]` on by default
+
+error[E0080]: evaluation of constant value failed
+ --> $DIR/validate_uninhabited_zsts.rs:4:14
+ |
+LL | unsafe { std::mem::transmute(()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type
+ |
+note: inside `foo`
+ --> $DIR/validate_uninhabited_zsts.rs:4:14
+ |
+LL | unsafe { std::mem::transmute(()) }
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+note: inside `FOO`
+ --> $DIR/validate_uninhabited_zsts.rs:19:33
+ |
+LL | const FOO: [empty::Empty; 3] = [foo(); 3];
+ | ^^^^^
+
+error[E0080]: it is undefined behavior to use this value
+ --> $DIR/validate_uninhabited_zsts.rs:21:1
+ |
+LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0].0: encountered a value of uninhabited type empty::Void
+ |
+ = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
+ = note: the raw bytes of the constant (size: 0, align: 1) {}
+
+warning: the type `empty::Empty` does not permit zero-initialization
+ --> $DIR/validate_uninhabited_zsts.rs:21:42
+ |
+LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ | |
+ | this code causes undefined behavior when executed
+ | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done
+ |
+note: in this struct field
+ --> $DIR/validate_uninhabited_zsts.rs:16:22
+ |
+LL | pub struct Empty(Void);
+ | ^^^^
+note: enums with no inhabited variants have no valid value
+ --> $DIR/validate_uninhabited_zsts.rs:13:5
+ |
+LL | enum Void {}
+ | ^^^^^^^^^
+
+error: aborting due to 2 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs b/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs
new file mode 100644
index 000000000..c0b326215
--- /dev/null
+++ b/tests/ui/consts/const-eval/validate_uninhabited_zsts.rs
@@ -0,0 +1,28 @@
+// stderr-per-bitwidth
+
+const fn foo() -> ! {
+ unsafe { std::mem::transmute(()) }
+ //~^ ERROR evaluation of constant value failed
+ //~| WARN the type `!` does not permit zero-initialization [invalid_value]
+}
+
+// Type defined in a submodule, so that it is not "visibly"
+// uninhabited (which would change interpreter behavior).
+pub mod empty {
+ #[derive(Clone, Copy)]
+ enum Void {}
+
+ #[derive(Clone, Copy)]
+ pub struct Empty(Void);
+}
+
+const FOO: [empty::Empty; 3] = [foo(); 3];
+
+const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3];
+//~^ ERROR it is undefined behavior to use this value
+//~| WARN the type `empty::Empty` does not permit zero-initialization
+
+fn main() {
+ FOO;
+ BAR;
+}
diff --git a/tests/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs b/tests/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs
new file mode 100644
index 000000000..cccb7879f
--- /dev/null
+++ b/tests/ui/consts/const-eval/write-to-uninhabited-enum-variant.rs
@@ -0,0 +1,28 @@
+// run-pass
+
+#![allow(dead_code)]
+
+enum Empty { }
+enum Test1 {
+ A(u8),
+ B(Empty),
+}
+enum Test2 {
+ A(u8),
+ B(Empty),
+ C,
+}
+
+fn bar() -> Option<Empty> {
+ None
+}
+
+fn main() {
+ if let Some(x) = bar() {
+ Test1::B(x);
+ }
+
+ if let Some(x) = bar() {
+ Test2::B(x);
+ }
+}
diff --git a/tests/ui/consts/const-eval/zst_operand_eval.rs b/tests/ui/consts/const-eval/zst_operand_eval.rs
new file mode 100644
index 000000000..5f7ddf7f7
--- /dev/null
+++ b/tests/ui/consts/const-eval/zst_operand_eval.rs
@@ -0,0 +1,5 @@
+// check-pass
+
+static ASSERT: () = [()][!(std::mem::size_of::<u32>() == 4) as usize];
+
+fn main() {}