Skip to content

Constant gets evaluated even when it contains invalid transmute #79047

Closed
@RalfJung

Description

@RalfJung

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:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)C-bugCategory: This is a bug.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions