@@ -2388,57 +2388,134 @@ impl<'tcx> Operand<'tcx> {
2388
2388
#[ derive( Clone , TyEncodable , TyDecodable , Hash , HashStable , PartialEq ) ]
2389
2389
/// The various kinds of rvalues that can appear in MIR.
2390
2390
///
2391
- /// Not all of these are allowed at every [`MirPhase`]. Check the documentation there to see which
2392
- /// ones you do not have to worry about. The MIR validator will generally enforce such restrictions,
2393
- /// causing an ICE if they are violated.
2391
+ /// Not all of these are allowed at every [`MirPhase`] - when this is the case, it's stated below.
2392
+ ///
2393
+ /// Computing any rvalue begins by evaluating the places and operands in the rvalue in the order in
2394
+ /// which they appear. These are then used to produce a "value" - the same kind of value that an
2395
+ /// [`Operand`] is.
2394
2396
pub enum Rvalue < ' tcx > {
2395
- /// x (either a move or copy, depending on type of x)
2397
+ /// Yields the operand unchanged
2396
2398
Use ( Operand < ' tcx > ) ,
2397
2399
2398
- /// [x; 32]
2400
+ /// Creates an array where each element is the value of the operand. This currently does not
2401
+ /// drop the value even if the number of repetitions is zero, see [#74836].
2402
+ ///
2403
+ /// Corresponds to source code like `[x; 32]`.
2404
+ ///
2405
+ /// [#74836]: https://github.com/rust-lang/rust/issues/74836
2399
2406
Repeat ( Operand < ' tcx > , ty:: Const < ' tcx > ) ,
2400
2407
2401
- /// &x or &mut x
2408
+ /// Creates a reference of the indicated kind to the place.
2409
+ ///
2410
+ /// There is not much to document here, because besides the obvious parts the semantics of this
2411
+ /// are essentially entirely a part of the aliasing model. There are many UCG issues discussing
2412
+ /// exactly what the behavior of this operation should be.
2413
+ ///
2414
+ /// `Shallow` borrows are disallowed after drop lowering.
2402
2415
Ref ( Region < ' tcx > , BorrowKind , Place < ' tcx > ) ,
2403
2416
2404
- /// Accessing a thread local static. This is inherently a runtime operation, even if llvm
2405
- /// treats it as an access to a static. This `Rvalue` yields a reference to the thread local
2406
- /// static.
2417
+ /// Returns a pointer/reference to the given thread local.
2418
+ ///
2419
+ /// The yielded type is a `*mut T` if the static is mutable, otherwise if the static is extern a
2420
+ /// `*const T`, and if neither of those apply a `&T`.
2421
+ ///
2422
+ /// **Note:** This is a runtime operation that actually executes code and is in this sense more
2423
+ /// like a function call. Also, DSEing these causes `fn main() {}` to SIGILL for some reason
2424
+ /// that I never got a chance to look into.
2425
+ ///
2426
+ /// **Needs clarification**: Are there weird additional semantics here related to the runtime
2427
+ /// nature of this operation?
2407
2428
ThreadLocalRef ( DefId ) ,
2408
2429
2409
- /// Create a raw pointer to the given place
2410
- /// Can be generated by raw address of expressions (`&raw const x`),
2411
- /// or when casting a reference to a raw pointer.
2430
+ /// Creates a pointer with the indicated mutability to the place.
2431
+ ///
2432
+ /// This is generated by pointer casts like `&v as *const _` or raw address of expressions like
2433
+ /// `&raw v` or `addr_of!(v)`.
2434
+ ///
2435
+ /// Like with references, the semantics of this operation are heavily dependent on the aliasing
2436
+ /// model.
2412
2437
AddressOf ( Mutability , Place < ' tcx > ) ,
2413
2438
2414
- /// length of a `[X]` or `[X;n]` value
2439
+ /// Yields the length of the place, as a `usize`.
2440
+ ///
2441
+ /// If the type of the place is an array, this is the array length. This also works for slices
2442
+ /// (`[T]`, not `&[T]`) through some mechanism that depends on how exactly places work (see
2443
+ /// there for more details).
2415
2444
Len ( Place < ' tcx > ) ,
2416
2445
2446
+ /// Performs essentially all of the casts that can be performed via `as`.
2447
+ ///
2448
+ /// This allows for casts from/to a variety of types.
2449
+ ///
2450
+ /// **FIXME**: Document exactly which `CastKind`s allow which types of casts. Figure out why
2451
+ /// `ArrayToPointer` and `MutToConstPointer` are special.
2417
2452
Cast ( CastKind , Operand < ' tcx > , Ty < ' tcx > ) ,
2418
2453
2454
+ /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
2455
+ /// paramter may be a `usize` as well.
2456
+ /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
2457
+ /// raw pointers, or function pointers and return a `bool`.
2458
+ /// * Left and right shift operations accept signed or unsigned integers not necessarily of the
2459
+ /// same type and return a value of the same type as their LHS. For all other operations, the
2460
+ /// types of the operands must match.
2461
+ /// * The `Bit*` operations accept signed integers, unsigned integers, or bools and return a
2462
+ /// value of that type.
2463
+ /// * The remaining operations accept signed integers, unsigned integers, or floats of any
2464
+ /// matching type and return a value of that type.
2419
2465
BinaryOp ( BinOp , Box < ( Operand < ' tcx > , Operand < ' tcx > ) > ) ,
2466
+
2467
+ /// Same as `BinaryOp`, but yields `(T, bool)` instead of `T`. In addition to performing the
2468
+ /// same computation as the matching `BinaryOp`, checks if the infinite precison result would be
2469
+ /// unequal to the actual result and sets the `bool` if this is the case. `BinOp::Offset` is not
2470
+ /// allowed here.
2471
+ ///
2472
+ /// **FIXME**: What about division/modulo? Are they allowed here at all? Are zero divisors still
2473
+ /// UB? Also, which other combinations of types are disallowed?
2420
2474
CheckedBinaryOp ( BinOp , Box < ( Operand < ' tcx > , Operand < ' tcx > ) > ) ,
2421
2475
2476
+ /// Yields the size or alignment of the type as a `usize`.
2422
2477
NullaryOp ( NullOp , Ty < ' tcx > ) ,
2478
+
2479
+ /// Exactly like `BinaryOp`, but less operands.
2480
+ ///
2481
+ /// Also does two's-complement arithmetic. Negation requires a signed integer or a float; binary
2482
+ /// not requires a signed integer, unsigned integer, or bool. Both operation kinds return a
2483
+ /// value with the same type as their operand.
2423
2484
UnaryOp ( UnOp , Operand < ' tcx > ) ,
2424
2485
2425
- /// Read the discriminant of an ADT.
2486
+ /// Computes the discriminant of the place, returning it as an integer of type
2487
+ /// [`discriminant_ty`].
2488
+ ///
2489
+ /// The validity requirements for the underlying value are undecided for this rvalue, see
2490
+ /// [#91095]. Note too that the value of the discriminant is not the same thing as the
2491
+ /// variant index; use [`discriminant_for_variant`] to convert.
2492
+ ///
2493
+ /// For types defined in the source code as enums, this is well behaved. This is also well
2494
+ /// formed for other types, but yields no particular value - there is no reason it couldn't be
2495
+ /// defined to yield eg zero though.
2426
2496
///
2427
- /// Undefined (i.e., no effort is made to make it defined, but there’s no reason why it cannot
2428
- /// be defined to return, say, a 0) if ADT is not an enum.
2497
+ /// [`discriminant_ty`]: crate::ty::Ty::discriminant_ty
2498
+ /// [#91095]: https://github.com/rust-lang/rust/issues/91095
2499
+ /// [`discriminant_for_variant`]: crate::ty::Ty::discriminant_for_variant
2429
2500
Discriminant ( Place < ' tcx > ) ,
2430
2501
2431
- /// Creates an aggregate value, like a tuple or struct. This is
2432
- /// only needed because we want to distinguish `dest = Foo { x:
2433
- /// ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case
2434
- /// that `Foo` has a destructor. These rvalues can be optimized
2435
- /// away after type-checking and before lowering.
2502
+ /// Creates an aggregate value, like a tuple or struct.
2503
+ ///
2504
+ /// This is needed because dataflow analysis needs to distinguish
2505
+ /// `dest = Foo { x: ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case that `Foo`
2506
+ /// has a destructor.
2507
+ ///
2508
+ /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
2509
+ /// generator lowering, `Generator` aggregate kinds are disallowed too.
2436
2510
Aggregate ( Box < AggregateKind < ' tcx > > , Vec < Operand < ' tcx > > ) ,
2437
2511
2438
2512
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
2439
2513
///
2440
- /// This is different a normal transmute because dataflow analysis will treat the box
2441
- /// as initialized but its content as uninitialized.
2514
+ /// This is different a normal transmute because dataflow analysis will treat the box as
2515
+ /// initialized but its content as uninitialized. Like other pointer casts, this in general
2516
+ /// affects alias analysis.
2517
+ ///
2518
+ /// Disallowed after drop elaboration.
2442
2519
ShallowInitBox ( Operand < ' tcx > , Ty < ' tcx > ) ,
2443
2520
}
2444
2521
0 commit comments