Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

require full validity when determining the discriminant of a value #90895

Merged
merged 1 commit into from
Nov 18, 2021

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Nov 14, 2021

This resolves (for now) the semantic question that came up in #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 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:

#[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

@rust-highfive
Copy link
Collaborator

Some changes occured to the CTFE / Miri engine

cc @rust-lang/miri

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 14, 2021
@rust-log-analyzer

This comment has been minimized.

@RalfJung
Copy link
Member Author

This is WIP since I cannot bless the ui tests due to #90812.

Actually, that failure is legit -- this change made discriminant reading and validation mutually recursive. D'oh.

@RalfJung RalfJung changed the title WIP: CTFE read_discriminant: require operand to be fully valid require full validity when determining the discriminant of a value Nov 14, 2021
@RalfJung
Copy link
Member Author

RalfJung commented Nov 14, 2021

I changed the PR to use a different approach -- but now it has no effect during CTFE, so it cannot be tested here.
rust-lang/miri#1914 adds a test to Miri.

@oli-obk
Copy link
Contributor

oli-obk commented Nov 18, 2021

@bors r+ rollup

@bors
Copy link
Contributor

bors commented Nov 18, 2021

📌 Commit 498ebc4 has been approved by oli-obk

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 18, 2021
JohnTitor added a commit to JohnTitor/rust that referenced this pull request Nov 18, 2021
…=oli-obk

require full validity when determining the discriminant of a value

This resolves (for now) the semantic question that came up in rust-lang#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`
@apiraino apiraino added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Nov 18, 2021
bors added a commit to rust-lang-ci/rust that referenced this pull request Nov 18, 2021
Rollup of 8 pull requests

Successful merges:

 - rust-lang#90386 (Add `-Zassert-incr-state` to assert state of incremental cache)
 - rust-lang#90438 (Clean up mess for --show-coverage documentation)
 - rust-lang#90480 (Mention `Vec::remove` in `Vec::swap_remove`'s docs)
 - rust-lang#90607 (Make slice->str conversion and related functions `const`)
 - rust-lang#90750 (rustdoc: Replace where-bounded Clean impl with simple function)
 - rust-lang#90895 (require full validity when determining the discriminant of a value)
 - rust-lang#90989 (Avoid suggesting literal formatting that turns into member access)
 - rust-lang#91002 (rustc: Remove `#[rustc_synthetic]`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 0a2b7d7 into rust-lang:master Nov 18, 2021
@rustbot rustbot added this to the 1.58.0 milestone Nov 18, 2021
@RalfJung
Copy link
Member Author

Ah, turns out this uncovered a quirk/bug in MIR building: #91029.

@RalfJung RalfJung deleted the read-discriminant-valid branch November 28, 2021 03:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants