]> git.lizzy.rs Git - rust.git/commitdiff
Ensure that we get a hard error on generic ZST constants if their body causes an...
authorOliver Scherer <github35764891676564198441@oli-obk.de>
Sun, 8 Dec 2019 00:55:14 +0000 (01:55 +0100)
committerOliver Scherer <github35764891676564198441@oli-obk.de>
Sun, 8 Dec 2019 00:55:14 +0000 (01:55 +0100)
src/librustc_codegen_ssa/mir/constant.rs
src/librustc_mir/transform/simplify.rs
src/test/ui/consts/assoc_const_generic_impl.rs [new file with mode: 0644]
src/test/ui/consts/assoc_const_generic_impl.stderr [new file with mode: 0644]

index 27891be6b82c5e45093cc7c9c6cac7c52c040cb8..fb8f504d04b10e118e8c1e7153e06aa6db4c824c 100644 (file)
@@ -16,6 +16,10 @@ pub fn eval_mir_constant_to_operand(
         constant: &mir::Constant<'tcx>,
     ) -> Result<OperandRef<'tcx, Bx::Value>, ErrorHandled> {
         match constant.literal.val {
+            // Special case unevaluated statics, because statics have an identity and thus should
+            // use `get_static` to get at their id.
+            // FIXME(oli-obk): can we unify this somehow, maybe by making const eval of statics
+            // always produce `&STATIC`. This may also simplify how const eval works with statics.
             ty::ConstKind::Unevaluated(def_id, substs)
                 if self.cx.tcx().is_static(def_id) => {
                     assert!(substs.is_empty(), "we don't support generic statics yet");
@@ -46,7 +50,10 @@ pub fn eval_mir_constant(
                     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)),
         }
index 900752d3ce06c2068bbcb526c140644e4c72afdd..6ce77a3057a0a2e56cf7a4bef2ed41bdfc1a3b4d 100644 (file)
@@ -29,7 +29,7 @@
 
 use rustc_index::bit_set::BitSet;
 use rustc_index::vec::{Idx, IndexVec};
-use rustc::ty::TyCtxt;
+use rustc::ty::{self, TyCtxt};
 use rustc::mir::*;
 use rustc::mir::visit::{MutVisitor, Visitor, PlaceContext, MutatingUseContext};
 use std::borrow::Cow;
@@ -367,9 +367,14 @@ fn visit_local(&mut self, local: &Local, ctx: PlaceContext, location: Location)
                 if let StatementKind::Assign(
                     box (p, Rvalue::Use(Operand::Constant(c)))
                 ) = &stmt.kind {
-                    if !p.is_indirect() {
-                        trace!("skipping store of const value {:?} to {:?}", c, p);
-                        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.
+                        ty::ConstKind::Unevaluated(..) => {}
+                        _ => if !p.is_indirect() {
+                            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 (file)
index 0000000..cce0cdb
--- /dev/null
@@ -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 (file)
index 0000000..3765a37
--- /dev/null
@@ -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
+