Skip to content

Commit 04a4692

Browse files
oli-obkMark-Simulacrum
authored andcommitted
Ensure that we get a hard error on generic ZST constants if their body causes an error during evaluation
1 parent a17c556 commit 04a4692

File tree

4 files changed

+39
-4
lines changed

4 files changed

+39
-4
lines changed

src/librustc_codegen_ssa/mir/constant.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
2323
instance,
2424
promoted: None,
2525
};
26-
self.cx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid))
26+
self.cx.tcx().const_eval(ty::ParamEnv::reveal_all().and(cid)).map_err(|err| {
27+
self.cx.tcx().sess.span_err(constant.span, "erroneous constant encountered");
28+
err
29+
})
2730
},
2831
_ => Ok(self.monomorphize(&constant.literal)),
2932
}

src/librustc_mir/transform/simplify.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,9 +363,14 @@ impl<'a, 'tcx> Visitor<'tcx> for DeclMarker<'a, 'tcx> {
363363
let stmt =
364364
&self.body.basic_blocks()[location.block].statements[location.statement_index];
365365
if let StatementKind::Assign(box (p, Rvalue::Use(Operand::Constant(c)))) = &stmt.kind {
366-
if p.as_local().is_some() {
367-
trace!("skipping store of const value {:?} to {:?}", c, local);
368-
return;
366+
match c.literal.val {
367+
// Keep assignments from unevaluated constants around, since the evaluation
368+
// may report errors, even if the use of the constant is dead code.
369+
interpret::ConstValue::Unevaluated(..) => {}
370+
_ => if p.as_local().is_some() {
371+
trace!("skipping store of const value {:?} to {:?}", c, p);
372+
return;
373+
},
369374
}
370375
}
371376
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#![allow(const_err)]
2+
3+
trait ZeroSized: Sized {
4+
const I_AM_ZERO_SIZED: ();
5+
fn requires_zero_size(self);
6+
}
7+
8+
impl<T: Sized> ZeroSized for T {
9+
const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::<Self>()];
10+
fn requires_zero_size(self) {
11+
let () = Self::I_AM_ZERO_SIZED; //~ ERROR erroneous constant encountered
12+
println!("requires_zero_size called");
13+
}
14+
}
15+
16+
fn main() {
17+
().requires_zero_size();
18+
42_u32.requires_zero_size();
19+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: erroneous constant encountered
2+
--> $DIR/assoc_const_generic_impl.rs:11:18
3+
|
4+
LL | let () = Self::I_AM_ZERO_SIZED;
5+
| ^^^^^^^^^^^^^^^^^^^^^
6+
7+
error: aborting due to previous error
8+

0 commit comments

Comments
 (0)