]> git.lizzy.rs Git - rust.git/commit
Rollup merge of #90895 - RalfJung:read-discriminant-valid, r=oli-obk
authorYuki Okushi <jtitor@2k36.org>
Thu, 18 Nov 2021 17:22:58 +0000 (02:22 +0900)
committerGitHub <noreply@github.com>
Thu, 18 Nov 2021 17:22:58 +0000 (02:22 +0900)
commit0a2b7d71d96a22126cce57f0dab5890d060f2259
tree2b031acb7ac22962694a56be1741b7561301479e
parent47c1bd1bcc50b25d133f8be3d49825491c1df249
parent498ebc46baf1d6f588f3b241f779a42edecf79be
Rollup merge of #90895 - RalfJung:read-discriminant-valid, r=oli-obk

require full validity when determining the discriminant of a value

This resolves (for now) the semantic question that came up in https://github.com/rust-lang/rust/pull/89764: arguably, reading the discriminant of a value is 'using' that value, so we are in our right to demand full validity. Reading a discriminant is somewhat special in that it works for values of *arbitrary* type; all the other primitive MIR operations work on specific types (e.g. `bool` or an integer) and basically implicitly require validity as part of just "doing their job".

The alternative would be to just require that the discriminant itself is valid, if any -- but then what do we do for types that do not have a discriminant, which kind of validity do we check? [This code](https://github.com/rust-lang/rust/blob/81117ff930fbf3792b4f9504e3c6bccc87b10823/compiler/rustc_codegen_ssa/src/mir/place.rs#L206-L215) means we have to at least reject uninhabited types, but I would rather not special case that.

I don't think this can be tested in CTFE (since validity is not enforced there), I will add a compile-fail test to Miri:
```rust
#[allow(enum_intrinsics_non_enums)]
fn main() {
    let i = 2u8;
    std::mem::discriminant(unsafe { &*(&i as *const _ as *const bool) }); // UB
}
```

(I tried running the check even on the CTFE machines, but then it runs during ConstProp and that causes all sorts of problems. We could run it for ConstEval but not ConstProp, but that simply does not seem worth the effort currently.)

r? ``@oli-obk``