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");
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)),
}
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;
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;
+ },
}
}
}
--- /dev/null
+#![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();
+}
--- /dev/null
+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
+