Skip to content

Commit 411ae6f

Browse files
committed
Address various comments and change some details around place to value conversions
1 parent 1d318e4 commit 411ae6f

File tree

3 files changed

+37
-36
lines changed

3 files changed

+37
-36
lines changed

compiler/rustc_const_eval/src/transform/validate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,7 +697,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
697697
TerminatorKind::Resume | TerminatorKind::Abort => {
698698
let bb = location.block;
699699
if !self.body.basic_blocks()[bb].is_cleanup {
700-
self.fail(location, "Cannot `Resume` from non-cleanup basic block")
700+
self.fail(location, "Cannot `Resume` or `Abort` from non-cleanup basic block")
701701
}
702702
}
703703
TerminatorKind::Return => {

compiler/rustc_middle/src/mir/mod.rs

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,16 +1653,15 @@ pub enum StatementKind<'tcx> {
16531653
/// statements are not required. If the entire MIR body contains no `StorageLive`/`StorageDead`
16541654
/// statements for a particular local, the local is always considered live.
16551655
///
1656-
/// More precisely, the MIR validator currently does a `MaybeLiveLocals` analysis to check
1657-
/// validity of each use of a local. I believe this is equivalent to requiring for every use of
1658-
/// a local, there exist at least one path from the root to that use that contains a
1656+
/// More precisely, the MIR validator currently does a `MaybeStorageLiveLocals` analysis to
1657+
/// check validity of each use of a local. I believe this is equivalent to requiring for every
1658+
/// use of a local, there exist at least one path from the root to that use that contains a
16591659
/// `StorageLive` more recently than a `StorageDead`.
16601660
///
1661-
/// **Needs clarification**: Is it permitted to `StorageLive` a local for which we previously
1662-
/// executed `StorageDead`? How about two `StorageLive`s without an intervening `StorageDead`?
1663-
/// Two `StorageDead`s without an intervening `StorageLive`? LLVM says yes, poison, yes. If the
1664-
/// answer to any of these is "no," is breaking that rule UB or is it an error to have a path in
1665-
/// the CFG that might do this?
1661+
/// **Needs clarification**: Is it permitted to have two `StorageLive`s without an intervening
1662+
/// `StorageDead`? Two `StorageDead`s without an intervening `StorageLive`? LLVM says poison,
1663+
/// yes. If the answer to any of these is "no," is breaking that rule UB or is it an error to
1664+
/// have a path in the CFG that might do this?
16661665
StorageLive(Local),
16671666

16681667
/// See `StorageLive` above.
@@ -1675,7 +1674,7 @@ pub enum StatementKind<'tcx> {
16751674
/// <https://internals.rust-lang.org/t/stacked-borrows-an-aliasing-model-for-rust/8153/> for
16761675
/// more details.
16771676
///
1678-
/// For code that is not specific to stacked borrows, you should consider statements to read
1677+
/// For code that is not specific to stacked borrows, you should consider retags to read
16791678
/// and modify the place in an opaque way.
16801679
Retag(RetagKind, Box<Place<'tcx>>),
16811680

@@ -1704,7 +1703,7 @@ pub enum StatementKind<'tcx> {
17041703
/// executed.
17051704
Coverage(Box<Coverage>),
17061705

1707-
/// Denotes a call to the intrinsic function `copy_overlapping`.
1706+
/// Denotes a call to the intrinsic function `copy_nonoverlapping`.
17081707
///
17091708
/// First, all three operands are evaluated. `src` and `dest` must each be a reference, pointer,
17101709
/// or `Box` pointing to the same type `T`. `count` must evaluate to a `usize`. Then, `src` and
@@ -1919,7 +1918,7 @@ pub struct CopyNonOverlapping<'tcx> {
19191918
/// **Needs clarification**: What about metadata resulting from dereferencing wide pointers (and
19201919
/// possibly from accessing unsized locals - not sure how those work)? That probably deserves to go
19211920
/// on the list above and be discussed too. It is also probably necessary for making the indexing
1922-
/// stuff lass hand-wavey.
1921+
/// stuff less hand-wavey.
19231922
///
19241923
/// **Needs clarification**: When it says "part of memory" what does that mean precisely, and how
19251924
/// does it interact with the metadata?
@@ -2334,13 +2333,13 @@ pub struct SourceScopeLocalData {
23342333
///
23352334
/// The most common way to create values is via a place to value conversion. A place to value
23362335
/// conversion is an operation which reads the memory of the place and converts it to a value. This
2337-
/// is a fundamentally *typed* operation. Different types will do different things. These are some
2338-
/// possible examples of what Rust may - but will not necessarily - decide to do on place to value
2339-
/// conversions:
2336+
/// is a fundamentally *typed* operation. The nature of the value produced depends on the type of
2337+
/// the conversion. Furthermore, there may be other effects: if the type has a validity constraint
2338+
/// the place to value conversion might be UB if the validity constraint is not met.
23402339
///
2341-
/// 1. Types with validity constraints cause UB if the validity constraint is not met
2342-
/// 2. References/pointers may have their provenance change or cause other provenance related
2343-
/// side-effects.
2340+
/// **Needs clarification:** Ralf proposes that place to value conversions not have side-effects.
2341+
/// This is what is implemented in miri today. Are these the semantics we want for MIR? Is this
2342+
/// something we can even decide without knowing more about Rust's memory model?
23442343
///
23452344
/// A place to value conversion on a place that has its variant index set is not well-formed.
23462345
/// However, note that this rule only applies to places appearing in MIR bodies. Many functions,
@@ -2472,15 +2471,17 @@ impl<'tcx> Operand<'tcx> {
24722471
///
24732472
/// Not all of these are allowed at every [`MirPhase`] - when this is the case, it's stated below.
24742473
///
2475-
/// Computing any rvalue begins by evaluating the places and operands in the rvalue in the order in
2476-
/// which they appear. These are then used to produce a "value" - the same kind of value that an
2477-
/// [`Operand`] is.
2474+
/// Computing any rvalue begins by evaluating the places and operands in some order (**Needs
2475+
/// clarification**: Which order?). These are then used to produce a "value" - the same kind of
2476+
/// value that an [`Operand`] is.
24782477
pub enum Rvalue<'tcx> {
24792478
/// Yields the operand unchanged
24802479
Use(Operand<'tcx>),
24812480

2482-
/// Creates an array where each element is the value of the operand. This currently does not
2483-
/// drop the value even if the number of repetitions is zero, see [#74836].
2481+
/// Creates an array where each element is the value of the operand.
2482+
///
2483+
/// This is the cause of a bug in the case where the repetition count is zero because the value
2484+
/// is not dropped, see [#74836].
24842485
///
24852486
/// Corresponds to source code like `[x; 32]`.
24862487
///
@@ -2534,12 +2535,12 @@ pub enum Rvalue<'tcx> {
25342535
Cast(CastKind, Operand<'tcx>, Ty<'tcx>),
25352536

25362537
/// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
2537-
/// paramter may be a `usize` as well.
2538+
/// parameter may be a `usize` as well.
25382539
/// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
25392540
/// raw pointers, or function pointers and return a `bool`.
25402541
/// * Left and right shift operations accept signed or unsigned integers not necessarily of the
25412542
/// same type and return a value of the same type as their LHS. For all other operations, the
2542-
/// types of the operands must match.
2543+
/// types of the operands must match. Like in Rust, the RHS is truncated as needed.
25432544
/// * The `Bit*` operations accept signed integers, unsigned integers, or bools and return a
25442545
/// value of that type.
25452546
/// * The remaining operations accept signed integers, unsigned integers, or floats of any
@@ -2548,21 +2549,19 @@ pub enum Rvalue<'tcx> {
25482549

25492550
/// Same as `BinaryOp`, but yields `(T, bool)` instead of `T`. In addition to performing the
25502551
/// same computation as the matching `BinaryOp`, checks if the infinite precison result would be
2551-
/// unequal to the actual result and sets the `bool` if this is the case. `BinOp::Offset` is not
2552-
/// allowed here.
2552+
/// unequal to the actual result and sets the `bool` if this is the case.
25532553
///
2554-
/// **FIXME**: What about division/modulo? Are they allowed here at all? Are zero divisors still
2555-
/// UB? Also, which other combinations of types are disallowed?
2554+
/// This only supports addition, subtraction, multiplication, and shift operations.
25562555
CheckedBinaryOp(BinOp, Box<(Operand<'tcx>, Operand<'tcx>)>),
25572556

2558-
/// Yields the size or alignment of the type as a `usize`.
2557+
/// Computes a value as described by the operation.
25592558
NullaryOp(NullOp, Ty<'tcx>),
25602559

25612560
/// Exactly like `BinaryOp`, but less operands.
25622561
///
2563-
/// Also does two's-complement arithmetic. Negation requires a signed integer or a float; binary
2564-
/// not requires a signed integer, unsigned integer, or bool. Both operation kinds return a
2565-
/// value with the same type as their operand.
2562+
/// Also does two's-complement arithmetic. Negation requires a signed integer or a float;
2563+
/// bitwise not requires a signed integer, unsigned integer, or bool. Both operation kinds
2564+
/// return a value with the same type as their operand.
25662565
UnaryOp(UnOp, Operand<'tcx>),
25672566

25682567
/// Computes the discriminant of the place, returning it as an integer of type

compiler/rustc_middle/src/mir/terminator.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,10 +234,12 @@ pub enum TerminatorKind<'tcx> {
234234

235235
/// Roughly speaking, evaluates the `func` operand and the arguments, and starts execution of
236236
/// the referred to function. The operand types must match the argument types of the function.
237-
/// The return place type must exactly match the return type. The type of the `func` operand
238-
/// must be callable, meaning either a function pointer, a function type, or a closure type.
237+
/// The return place type must match the return type. The type of the `func` operand must be
238+
/// callable, meaning either a function pointer, a function type, or a closure type.
239239
///
240-
/// **Needs clarification**: The exact semantics of this, see [#71117].
240+
/// **Needs clarification**: The exact semantics of this. Current backends rely on `move`
241+
/// operands not aliasing the return place. It is unclear how this is justified in MIR, see
242+
/// [#71117].
241243
///
242244
/// [#71117]: https://github.com/rust-lang/rust/issues/71117
243245
Call {

0 commit comments

Comments
 (0)