Closed RalfJung closed 4 years ago
Here is a testcase that currently ICEs:
#![feature(const_panic)]
#![feature(never_type)]
#![warn(const_err)]
struct PrintName<T>(T);
impl<T> PrintName<T> {
const VOID: ! = panic!();
}
fn no_codegen<T>() {
let _ = PrintName::<T>::VOID;
}
fn main() {
no_codegen::<i32>();
}
Even more interestingly, the same code is considered UB by Miri with -Zmir-opt-level=3
:
error: Undefined Behavior: entering unreachable code
--> const_err.rs:11:13
|
11 | let _ = PrintName::<T>::VOID;
| ^^^^^^^^^^^^^^^^^^^^ entering unreachable code
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
opt level 3 has some broken optimization in it, but I don't think that's the problem here. Why is it false UB? It's UB to run into a value of !
type, which we do here if we don't evaluate the constant.
It's UB in a safe program, so either it's false UB or Rust is unsound.
But there is no actual UB here (and normal codegen shows a compile-time error as it should), thus it is false UB.
oh :facepalm: yea makes sense
Codegen recently gained a loop to make sure that all constants required by the MIR actually error. Miri does not have anything like that yet, but we probably need that for soundness.