about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/librustc_mir/build/expr/into.rs9
-rw-r--r--src/test/mir-opt/retain-never-const.rs28
-rw-r--r--src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs18
-rw-r--r--src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr22
-rw-r--r--src/test/ui/consts/const-eval/panic-assoc-never-type.rs15
-rw-r--r--src/test/ui/consts/const-eval/panic-assoc-never-type.stderr24
-rw-r--r--src/test/ui/consts/const-eval/panic-never-type.rs11
-rw-r--r--src/test/ui/consts/const-eval/panic-never-type.stderr24
8 files changed, 150 insertions, 1 deletions
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index f5dc09ccebc..07a44b190b2 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -65,7 +65,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     _ => false,
                 };
 
-                unpack!(block = this.as_local_rvalue(block, source));
+                // (#66975) Source could be a const of type `!`, so has to
+                // exist in the generated MIR.
+                unpack!(block = this.as_temp(
+                    block,
+                    this.local_scope(),
+                    source,
+                    Mutability::Mut,
+                ));
 
                 // This is an optimization. If the expression was a call then we already have an
                 // unreachable block. Don't bother to terminate it and create a new one.
diff --git a/src/test/mir-opt/retain-never-const.rs b/src/test/mir-opt/retain-never-const.rs
new file mode 100644
index 00000000000..5d59b2f4842
--- /dev/null
+++ b/src/test/mir-opt/retain-never-const.rs
@@ -0,0 +1,28 @@
+// Regression test for #66975 - ensure that we don't keep unevaluated
+// `!`-typed constants until codegen.
+
+// Force generation of optimized mir for functions that do not reach codegen.
+// compile-flags: --emit mir,link
+
+#![feature(const_panic)]
+
+struct PrintName<T>(T);
+
+impl<T> PrintName<T> {
+    const VOID: ! = panic!();
+}
+
+fn no_codegen<T>() {
+    let _ = PrintName::<T>::VOID;
+}
+
+fn main() {}
+
+// END RUST SOURCE
+// START rustc.no_codegen.PreCodegen.after.mir
+// bb0: {
+//     StorageLive(_1);
+//     _1 = const PrintName::<T>::VOID;
+//     unreachable;
+// }
+// END rustc.no_codegen.PreCodegen.after.mir
diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs
new file mode 100644
index 00000000000..516ca4f3f77
--- /dev/null
+++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.rs
@@ -0,0 +1,18 @@
+// Regression test for #66975
+#![warn(const_err)]
+
+struct PrintName<T>(T);
+
+impl<T> PrintName<T> {
+    const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
+    //~^ WARN any use of this value will cause an error
+}
+
+fn f<T>() {
+    let _ = PrintName::<T>::VOID;
+    //~^ ERROR erroneous constant encountered
+}
+
+pub fn main() {
+    f::<()>();
+}
diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
new file mode 100644
index 00000000000..e2bd8d0cc85
--- /dev/null
+++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr
@@ -0,0 +1,22 @@
+warning: any use of this value will cause an error
+  --> $DIR/index-out-of-bounds-never-type.rs:7:61
+   |
+LL |     const VOID: ! = { let x = 0 * std::mem::size_of::<T>(); [][x] };
+   |     --------------------------------------------------------^^^^^---
+   |                                                             |
+   |                                                             index out of bounds: the len is 0 but the index is 0
+   |
+note: lint level defined here
+  --> $DIR/index-out-of-bounds-never-type.rs:2:9
+   |
+LL | #![warn(const_err)]
+   |         ^^^^^^^^^
+
+error: erroneous constant encountered
+  --> $DIR/index-out-of-bounds-never-type.rs:12:13
+   |
+LL |     let _ = PrintName::<T>::VOID;
+   |             ^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.rs b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs
new file mode 100644
index 00000000000..b39d9af5546
--- /dev/null
+++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.rs
@@ -0,0 +1,15 @@
+// Regression test for #66975
+#![warn(const_err)]
+#![feature(const_panic)]
+
+struct PrintName;
+
+impl PrintName {
+    const VOID: ! = panic!();
+    //~^ WARN any use of this value will cause an error
+}
+
+fn main() {
+    let _ = PrintName::VOID;
+    //~^ ERROR erroneous constant used
+}
diff --git a/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr
new file mode 100644
index 00000000000..c07c8c65a2f
--- /dev/null
+++ b/src/test/ui/consts/const-eval/panic-assoc-never-type.stderr
@@ -0,0 +1,24 @@
+warning: any use of this value will cause an error
+  --> $DIR/panic-assoc-never-type.rs:8:21
+   |
+LL |     const VOID: ! = panic!();
+   |     ----------------^^^^^^^^-
+   |                     |
+   |                     the evaluated program panicked at 'explicit panic', $DIR/panic-assoc-never-type.rs:8:21
+   |
+note: lint level defined here
+  --> $DIR/panic-assoc-never-type.rs:2:9
+   |
+LL | #![warn(const_err)]
+   |         ^^^^^^^^^
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: erroneous constant used
+  --> $DIR/panic-assoc-never-type.rs:13:13
+   |
+LL |     let _ = PrintName::VOID;
+   |             ^^^^^^^^^^^^^^^ referenced constant has errors
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/test/ui/consts/const-eval/panic-never-type.rs b/src/test/ui/consts/const-eval/panic-never-type.rs
new file mode 100644
index 00000000000..42eabbf5847
--- /dev/null
+++ b/src/test/ui/consts/const-eval/panic-never-type.rs
@@ -0,0 +1,11 @@
+// Regression test for #66975
+#![warn(const_err)]
+#![feature(const_panic)]
+
+const VOID: ! = panic!();
+//~^ WARN any use of this value will cause an error
+
+fn main() {
+    let _ = VOID;
+    //~^ ERROR erroneous constant used
+}
diff --git a/src/test/ui/consts/const-eval/panic-never-type.stderr b/src/test/ui/consts/const-eval/panic-never-type.stderr
new file mode 100644
index 00000000000..4fb11a61525
--- /dev/null
+++ b/src/test/ui/consts/const-eval/panic-never-type.stderr
@@ -0,0 +1,24 @@
+warning: any use of this value will cause an error
+  --> $DIR/panic-never-type.rs:5:17
+   |
+LL | const VOID: ! = panic!();
+   | ----------------^^^^^^^^-
+   |                 |
+   |                 the evaluated program panicked at 'explicit panic', $DIR/panic-never-type.rs:5:17
+   |
+note: lint level defined here
+  --> $DIR/panic-never-type.rs:2:9
+   |
+LL | #![warn(const_err)]
+   |         ^^^^^^^^^
+   = note: this warning originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
+
+error[E0080]: erroneous constant used
+  --> $DIR/panic-never-type.rs:9:13
+   |
+LL |     let _ = VOID;
+   |             ^^^^ referenced constant has errors
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.