about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs51
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/body.rs39
-rw-r--r--compiler/rustc_smir/src/stable_mir/ty.rs2
3 files changed, 85 insertions, 7 deletions
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 16744db7e4c..365ef368248 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -132,7 +132,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
         use mir::Rvalue::*;
         match self {
             Use(op) => stable_mir::mir::Rvalue::Use(op.stable(tables)),
-            Repeat(_, _) => todo!(),
+            Repeat(op, len) => stable_mir::mir::Rvalue::Repeat(op.stable(tables), opaque(len)),
             Ref(region, kind, place) => stable_mir::mir::Rvalue::Ref(
                 opaque(region),
                 kind.stable(tables),
@@ -145,7 +145,11 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
             }
             Len(place) => stable_mir::mir::Rvalue::Len(place.stable(tables)),
-            Cast(_, _, _) => todo!(),
+            Cast(cast_kind, op, ty) => stable_mir::mir::Rvalue::Cast(
+                cast_kind.stable(tables),
+                op.stable(tables),
+                tables.intern_ty(*ty),
+            ),
             BinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::BinaryOp(
                 bin_op.stable(tables),
                 ops.0.stable(tables),
@@ -163,8 +167,13 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 stable_mir::mir::Rvalue::UnaryOp(un_op.stable(tables), op.stable(tables))
             }
             Discriminant(place) => stable_mir::mir::Rvalue::Discriminant(place.stable(tables)),
-            Aggregate(_, _) => todo!(),
-            ShallowInitBox(_, _) => todo!(),
+            Aggregate(agg_kind, operands) => {
+                let operands = operands.iter().map(|op| op.stable(tables)).collect();
+                stable_mir::mir::Rvalue::Aggregate(agg_kind.stable(tables), operands)
+            }
+            ShallowInitBox(op, ty) => {
+                stable_mir::mir::Rvalue::ShallowInitBox(op.stable(tables), tables.intern_ty(*ty))
+            }
             CopyForDeref(place) => stable_mir::mir::Rvalue::CopyForDeref(place.stable(tables)),
         }
     }
@@ -478,6 +487,40 @@ impl<'tcx> Stable<'tcx> for mir::UnOp {
     }
 }
 
+impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
+    type T = stable_mir::mir::AggregateKind;
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        match self {
+            mir::AggregateKind::Array(ty) => {
+                stable_mir::mir::AggregateKind::Array(tables.intern_ty(*ty))
+            }
+            mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple,
+            mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
+                stable_mir::mir::AggregateKind::Adt(
+                    rustc_internal::adt_def(*def_id),
+                    var_idx.index(),
+                    generic_arg.stable(tables),
+                    user_ty_index.map(|idx| idx.index()),
+                    field_idx.map(|idx| idx.index()),
+                )
+            }
+            mir::AggregateKind::Closure(def_id, generic_arg) => {
+                stable_mir::mir::AggregateKind::Closure(
+                    rustc_internal::closure_def(*def_id),
+                    generic_arg.stable(tables),
+                )
+            }
+            mir::AggregateKind::Generator(def_id, generic_arg, movability) => {
+                stable_mir::mir::AggregateKind::Generator(
+                    rustc_internal::generator_def(*def_id),
+                    generic_arg.stable(tables),
+                    movability.stable(tables),
+                )
+            }
+        }
+    }
+}
+
 impl<'tcx> Stable<'tcx> for rustc_hir::GeneratorKind {
     type T = stable_mir::mir::GeneratorKind;
     fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs
index 1b1871bcd2a..e08359067df 100644
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs
@@ -1,4 +1,6 @@
-use crate::stable_mir::ty::Region;
+use crate::stable_mir::ty::{
+    AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region,
+};
 use crate::stable_mir::{self, ty::Ty};
 
 #[derive(Clone, Debug)]
@@ -137,7 +139,6 @@ pub enum Statement {
     Nop,
 }
 
-// FIXME this is incomplete
 #[derive(Clone, Debug)]
 pub enum Rvalue {
     /// Creates a pointer with the indicated mutability to the place.
@@ -146,6 +147,16 @@ pub enum Rvalue {
     /// `&raw v` or `addr_of!(v)`.
     AddressOf(Mutability, Place),
 
+    /// Creates an aggregate value, like a tuple or struct.
+    ///
+    /// This is needed because dataflow analysis needs to distinguish
+    /// `dest = Foo { x: ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case that `Foo`
+    /// has a destructor.
+    ///
+    /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Generator`. After
+    /// generator lowering, `Generator` aggregate kinds are disallowed too.
+    Aggregate(AggregateKind, Vec<Operand>),
+
     /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
     ///   parameter may be a `usize` as well.
     /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
@@ -198,6 +209,16 @@ pub enum Rvalue {
     /// Creates a reference to the place.
     Ref(Region, BorrowKind, Place),
 
+    /// Creates an array where each element is the value of the operand.
+    ///
+    /// This is the cause of a bug in the case where the repetition count is zero because the value
+    /// is not dropped, see [#74836].
+    ///
+    /// Corresponds to source code like `[x; 32]`.
+    ///
+    /// [#74836]: https://github.com/rust-lang/rust/issues/74836
+    Repeat(Operand, Const),
+
     /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.
     ///
     /// This is different from a normal transmute because dataflow analysis will treat the box as
@@ -233,6 +254,15 @@ pub enum Rvalue {
 }
 
 #[derive(Clone, Debug)]
+pub enum AggregateKind {
+    Array(Ty),
+    Tuple,
+    Adt(AdtDef, VariantIdx, GenericArgs, Option<UserTypeAnnotationIndex>, Option<FieldIdx>),
+    Closure(ClosureDef, GenericArgs),
+    Generator(GeneratorDef, GenericArgs, Movability),
+}
+
+#[derive(Clone, Debug)]
 pub enum Operand {
     Copy(Place),
     Move(Place),
@@ -247,6 +277,11 @@ pub struct Place {
 
 type FieldIdx = usize;
 
+/// The source-order index of a variant in a type.
+type VariantIdx = usize;
+
+type UserTypeAnnotationIndex = usize;
+
 #[derive(Clone, Debug)]
 pub struct SwitchTarget {
     pub value: u128,
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/rustc_smir/src/stable_mir/ty.rs
index 7a72afd666c..025225b8d19 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/rustc_smir/src/stable_mir/ty.rs
@@ -10,7 +10,7 @@ impl Ty {
     }
 }
 
-type Const = Opaque;
+pub(crate) type Const = Opaque;
 pub(crate) type Region = Opaque;
 type Span = Opaque;