diff options
| author | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2019-12-08 01:55:14 +0100 |
|---|---|---|
| committer | Mark Rousskov <mark.simulacrum@gmail.com> | 2019-12-14 10:51:51 -0500 |
| commit | 04a46929f2c53fb9e20c182f8be02566eb31c65f (patch) | |
| tree | 3ec45f48cc615d6cce08b1304b8d75f70292f6c3 | |
| parent | a17c556bd088570c5c742eee8d36838dfa874878 (diff) | |
| download | rust-04a46929f2c53fb9e20c182f8be02566eb31c65f.tar.gz rust-04a46929f2c53fb9e20c182f8be02566eb31c65f.zip | |
Ensure that we get a hard error on generic ZST constants if their body causes an error during evaluation
| -rw-r--r-- | src/librustc_codegen_ssa/mir/constant.rs | 5 | ||||
| -rw-r--r-- | src/librustc_mir/transform/simplify.rs | 11 | ||||
| -rw-r--r-- | src/test/ui/consts/assoc_const_generic_impl.rs | 19 | ||||
| -rw-r--r-- | src/test/ui/consts/assoc_const_generic_impl.stderr | 8 |
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 + |
