about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_codegen_ssa/mir/constant.rs5
-rw-r--r--src/librustc_mir/transform/simplify.rs11
-rw-r--r--src/test/ui/consts/assoc_const_generic_impl.rs19
-rw-r--r--src/test/ui/consts/assoc_const_generic_impl.stderr8
4 files changed, 39 insertions, 4 deletions
diff --git a/src/librustc_codegen_ssa/mir/constant.rs b/src/librustc_codegen_ssa/mir/constant.rs
index d06359ab0ce..72d098eb311 100644
--- a/src/librustc_codegen_ssa/mir/constant.rs
+++ b/src/librustc_codegen_ssa/mir/constant.rs
@@ -23,7 +23,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     instance,
                     promoted: None,
                 };
-                self.cx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid))
+                self.cx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid)).map_err(|err| {
+                    self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
+                    err
+                })
             },
             _ => Ok(self.monomorphize(&constant.literal)),
         }
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index 1b90ea78c64..385fc7ed2cd 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -363,9 +363,14 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> {
             let stmt =
                 &self.body.basic_blocks()[location.block].statements[location.statement_index];
             if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(c)))) = &stmt.kind {
-                if p.as_local().is_some() {
-                    trace!("skipping store of const value {:?} to {:?}", c, local);
-                    return;
+                match c.literal.val {
+                    // Keep assignments from unevaluated constants around, since the evaluation
+                    // may report errors, even if the use of the constant is dead code.
+                    interpret::ConstValue::Unevaluated(..) => {}
+                    _ => if p.as_local().is_some() {
+                        trace!("skipping store of const value {:?} to {:?}", c, p);
+                        return;
+                    },
                 }
             }
         }
diff --git a/src/test/ui/consts/assoc_const_generic_impl.rs b/src/test/ui/consts/assoc_const_generic_impl.rs
new file mode 100644
index 00000000000..cce0cdbf8c5
--- /dev/null
+++ b/src/test/ui/consts/assoc_const_generic_impl.rs
@@ -0,0 +1,19 @@
+#![allow(const_err)]
+
+trait ZeroSized: Sized {
+    const I_AM_ZERO_SIZED: ();
+    fn requires_zero_size(self);
+}
+
+impl<T: Sized> ZeroSized for T {
+    const I_AM_ZERO_SIZED: ()  = [()][std::mem::size_of::<Self>()];
+    fn requires_zero_size(self) {
+        let () = Self::I_AM_ZERO_SIZED; //~ ERROR erroneous constant encountered
+        println!("requires_zero_size called");
+    }
+}
+
+fn main() {
+    ().requires_zero_size();
+    42_u32.requires_zero_size();
+}
diff --git a/src/test/ui/consts/assoc_const_generic_impl.stderr b/src/test/ui/consts/assoc_const_generic_impl.stderr
new file mode 100644
index 00000000000..3765a3703c7
--- /dev/null
+++ b/src/test/ui/consts/assoc_const_generic_impl.stderr
@@ -0,0 +1,8 @@
+error: erroneous constant encountered
+  --> $DIR/assoc_const_generic_impl.rs:11:18
+   |
+LL |         let () = Self::I_AM_ZERO_SIZED;
+   |                  ^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+