Skip to content

Commit

Permalink
Rollup merge of rust-lang#67134 - oli-obk:const_prop_zst, r=wesleywiser
Browse files Browse the repository at this point in the history
Ensure that we get a hard error on generic ZST constants if their bod…

…y causes an error during evaluation

cc rust-lang#67083 (does not fix because we still need the beta backport)

r? @wesleywiser

cc @RalfJung
  • Loading branch information
JohnTitor authored Dec 10, 2019
2 parents 9b1b12b + c143471 commit a7f9307
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 5 deletions.
9 changes: 8 additions & 1 deletion src/librustc_codegen_ssa/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
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");
Expand Down Expand Up @@ -46,7 +50,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)),
}
Expand Down
13 changes: 9 additions & 4 deletions src/librustc_mir/transform/simplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -367,9 +367,14 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> {
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;
},
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions src/test/ui/consts/assoc_const_generic_impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#![warn(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>()]; //~ WARN any use of this value
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();
}
22 changes: 22 additions & 0 deletions src/test/ui/consts/assoc_const_generic_impl.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
warning: any use of this value will cause an error
--> $DIR/assoc_const_generic_impl.rs:9:34
|
LL | const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::<Self>()];
| -----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| index out of bounds: the len is 1 but the index is 4
|
note: lint level defined here
--> $DIR/assoc_const_generic_impl.rs:1:9
|
LL | #![warn(const_err)]
| ^^^^^^^^^

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

0 comments on commit a7f9307

Please sign in to comment.