Skip to content

Commit 0a39e3c

Browse files
committed
Adjust documentation of SetDiscriminant to describe the semantics more precisely.
The changed semantics also make one analysis work better as written, so we remove the documentation in it that is now out of date.
1 parent ebac049 commit 0a39e3c

File tree

2 files changed

+15
-25
lines changed

2 files changed

+15
-25
lines changed

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,21 @@ pub enum StatementKind<'tcx> {
15531553
/// never accessed still get some sanity checks for, e.g., `let x: ! = ..;`
15541554
FakeRead(Box<(FakeReadCause, Place<'tcx>)>),
15551555

1556-
/// Write the discriminant for a variant to the enum Place.
1556+
/// Initialize the place with the given variant and all fields uninit.
1557+
///
1558+
/// If `place` is an ADT, this corresponds to the Rust code `place = Variant(uninit, uninit,
1559+
/// uninit)`. If each of the fields is initialized after the `SetDiscriminant`, the place is
1560+
/// completely initialized. Of course, you cannot initialize the fields first, as
1561+
/// `SetDiscriminant` invalidates them.
1562+
///
1563+
/// Computing the `Rvalue::Discriminant` of this place after `SetDiscriminant` is not
1564+
/// necessarily well defined if the fields have not also been initialized. See [#91095][91095]
1565+
/// for discussion around this topic.
1566+
///
1567+
/// If `place` is a generator, then this invalidates only those fields which are not also
1568+
/// present in another variant. Those fields that are present in another variant are unchanged.
1569+
///
1570+
/// [91095]: https://github.com/rust-lang/rust/issues/91095
15571571
SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
15581572

15591573
/// Start a live range for the storage of the local.

compiler/rustc_mir_dataflow/src/impls/liveness.rs

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,30 +18,6 @@ use crate::{AnalysisDomain, Backward, CallReturnPlaces, GenKill, GenKillAnalysis
1818
/// such an assignment is currently marked as a "use" of `x` in an attempt to be maximally
1919
/// conservative.
2020
///
21-
/// ## Enums and `SetDiscriminant`
22-
///
23-
/// Assigning a literal value to an `enum` (e.g. `Option<i32>`), does not result in a simple
24-
/// assignment of the form `_1 = /*...*/` in the MIR. For example, the following assignment to `x`:
25-
///
26-
/// ```
27-
/// x = Some(4);
28-
/// ```
29-
///
30-
/// compiles to this MIR
31-
///
32-
/// ```
33-
/// ((_1 as Some).0: i32) = const 4_i32;
34-
/// discriminant(_1) = 1;
35-
/// ```
36-
///
37-
/// However, `MaybeLiveLocals` **does** mark `x` (`_1`) as "killed" after a statement like this.
38-
/// That's because it treats the `SetDiscriminant` operation as a definition of `x`, even though
39-
/// the writes that actually initialized the locals happened earlier.
40-
///
41-
/// This makes `MaybeLiveLocals` unsuitable for certain classes of optimization normally associated
42-
/// with a live variables analysis, notably dead-store elimination. It's a dirty hack, but it works
43-
/// okay for the generator state transform (currently the main consumuer of this analysis).
44-
///
4521
/// [`MaybeBorrowedLocals`]: super::MaybeBorrowedLocals
4622
/// [flow-test]: https://github.com/rust-lang/rust/blob/a08c47310c7d49cbdc5d7afb38408ba519967ecd/src/test/ui/mir-dataflow/liveness-ptr.rs
4723
/// [liveness]: https://en.wikipedia.org/wiki/Live_variable_analysis

0 commit comments

Comments
 (0)