-
Couldn't load subscription status.
- Fork 13.9k
Description
Consider the following code:
const DST: &[u8] = unsafe { std::mem::transmute(1usize) };
fn main() {
match &b""[..] {
DST => {}
}
}This code hits a peculiar code path in the interpreter:
rust/compiler/rustc_mir/src/interpret/place.rs
Lines 916 to 927 in 30e49a9
| if src.layout.size != dest.layout.size { | |
| // FIXME: This should be an assert instead of an error, but if we transmute within an | |
| // array length computation, `typeck` may not have yet been run and errored out. In fact | |
| // most likey we *are* running `typeck` right now. Investigate whether we can bail out | |
| // on `typeck_results().has_errors` at all const eval entry points. | |
| debug!("Size mismatch when transmuting!\nsrc: {:#?}\ndest: {:#?}", src, dest); | |
| self.tcx.sess.delay_span_bug( | |
| self.cur_span(), | |
| "size-changing transmute, should have been caught by transmute checking", | |
| ); | |
| throw_inval!(TransmuteSizeDiff(src.layout.ty, dest.layout.ty)); | |
| } |
This code path should be unreachable: just like the interpreter can assume that code code it runs on is well-typed, it should be able to assume that the code it runs on has its transmutes checked. But something seems to be different about transmute when compared with "normal" type-checking.
TransmuteSizeDiff is a hack; we should instead arrange things in a way that failing the transmute check inhibits const-evaluation the same way that true + 4 inhibitis const-evaluation.