about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_smir/Cargo.toml1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs118
-rw-r--r--compiler/rustc_smir/src/stable_mir/mir/body.rs67
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs15
5 files changed, 191 insertions, 11 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d7806b5daa6..c7a91ef7116 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4090,6 +4090,7 @@ dependencies = [
 name = "rustc_smir"
 version = "0.0.0"
 dependencies = [
+ "rustc_hir",
  "rustc_middle",
  "rustc_span",
  "tracing",
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index fb97ee5bebe..80360a3c73f 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -4,6 +4,7 @@ version = "0.0.0"
 edition = "2021"
 
 [dependencies]
+rustc_hir = { path = "../rustc_hir" }
 rustc_middle = { path = "../rustc_middle", optional = true }
 rustc_span = { path = "../rustc_span", optional = true }
 tracing = "0.1"
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 57ceb89969d..efbb3b321d5 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -93,10 +93,10 @@ fn rustc_statement_to_statement(
     }
 }
 
-fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir::mir::Operand {
+fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir::mir::Rvalue {
     use rustc_middle::mir::Rvalue::*;
     match rvalue {
-        Use(op) => rustc_op_to_op(op),
+        Use(op) => stable_mir::mir::Rvalue::Use(rustc_op_to_op(op)),
         Repeat(_, _) => todo!(),
         Ref(_, _, _) => todo!(),
         ThreadLocalRef(_) => todo!(),
@@ -104,9 +104,15 @@ fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir:
         Len(_) => todo!(),
         Cast(_, _, _) => todo!(),
         BinaryOp(_, _) => todo!(),
-        CheckedBinaryOp(_, _) => todo!(),
+        CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp(
+            rustc_bin_op_to_bin_op(bin_op),
+            rustc_op_to_op(&ops.0),
+            rustc_op_to_op(&ops.1),
+        ),
         NullaryOp(_, _) => todo!(),
-        UnaryOp(_, _) => todo!(),
+        UnaryOp(un_op, op) => {
+            stable_mir::mir::Rvalue::UnaryOp(rustc_un_op_to_un_op(un_op), rustc_op_to_op(op))
+        }
         Discriminant(_) => todo!(),
         Aggregate(_, _) => todo!(),
         ShallowInitBox(_, _) => todo!(),
@@ -124,8 +130,10 @@ fn rustc_op_to_op(op: &rustc_middle::mir::Operand<'_>) -> stable_mir::mir::Opera
 }
 
 fn rustc_place_to_place(place: &rustc_middle::mir::Place<'_>) -> stable_mir::mir::Place {
-    assert_eq!(&place.projection[..], &[]);
-    stable_mir::mir::Place { local: place.local.as_usize() }
+    stable_mir::mir::Place {
+        local: place.local.as_usize(),
+        projection: format!("{:?}", place.projection),
+    }
 }
 
 fn rustc_unwind_to_unwind(
@@ -140,6 +148,96 @@ fn rustc_unwind_to_unwind(
     }
 }
 
+fn rustc_assert_msg_to_msg<'tcx>(
+    assert_message: &rustc_middle::mir::AssertMessage<'tcx>,
+) -> stable_mir::mir::AssertMessage {
+    use rustc_middle::mir::AssertKind;
+    match assert_message {
+        AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck {
+            len: rustc_op_to_op(len),
+            index: rustc_op_to_op(index),
+        },
+        AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow(
+            rustc_bin_op_to_bin_op(bin_op),
+            rustc_op_to_op(op1),
+            rustc_op_to_op(op2),
+        ),
+        AssertKind::OverflowNeg(op) => {
+            stable_mir::mir::AssertMessage::OverflowNeg(rustc_op_to_op(op))
+        }
+        AssertKind::DivisionByZero(op) => {
+            stable_mir::mir::AssertMessage::DivisionByZero(rustc_op_to_op(op))
+        }
+        AssertKind::RemainderByZero(op) => {
+            stable_mir::mir::AssertMessage::RemainderByZero(rustc_op_to_op(op))
+        }
+        AssertKind::ResumedAfterReturn(generator) => {
+            stable_mir::mir::AssertMessage::ResumedAfterReturn(rustc_generator_to_generator(
+                generator,
+            ))
+        }
+        AssertKind::ResumedAfterPanic(generator) => {
+            stable_mir::mir::AssertMessage::ResumedAfterPanic(rustc_generator_to_generator(
+                generator,
+            ))
+        }
+        AssertKind::MisalignedPointerDereference { required, found } => {
+            stable_mir::mir::AssertMessage::MisalignedPointerDereference {
+                required: rustc_op_to_op(required),
+                found: rustc_op_to_op(found),
+            }
+        }
+    }
+}
+
+fn rustc_bin_op_to_bin_op(bin_op: &rustc_middle::mir::BinOp) -> stable_mir::mir::BinOp {
+    use rustc_middle::mir::BinOp;
+    match bin_op {
+        BinOp::Add => stable_mir::mir::BinOp::Add,
+        BinOp::Sub => stable_mir::mir::BinOp::Sub,
+        BinOp::Mul => stable_mir::mir::BinOp::Mul,
+        BinOp::Div => stable_mir::mir::BinOp::Div,
+        BinOp::Rem => stable_mir::mir::BinOp::Rem,
+        BinOp::BitXor => stable_mir::mir::BinOp::BitXor,
+        BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd,
+        BinOp::BitOr => stable_mir::mir::BinOp::BitOr,
+        BinOp::Shl => stable_mir::mir::BinOp::Shl,
+        BinOp::Shr => stable_mir::mir::BinOp::Shr,
+        BinOp::Eq => stable_mir::mir::BinOp::Eq,
+        BinOp::Lt => stable_mir::mir::BinOp::Lt,
+        BinOp::Le => stable_mir::mir::BinOp::Le,
+        BinOp::Ne => stable_mir::mir::BinOp::Ne,
+        BinOp::Ge => stable_mir::mir::BinOp::Ge,
+        BinOp::Gt => stable_mir::mir::BinOp::Gt,
+        BinOp::Offset => stable_mir::mir::BinOp::Offset,
+    }
+}
+
+fn rustc_un_op_to_un_op(unary_op: &rustc_middle::mir::UnOp) -> stable_mir::mir::UnOp {
+    use rustc_middle::mir::UnOp;
+    match unary_op {
+        UnOp::Not => stable_mir::mir::UnOp::Not,
+        UnOp::Neg => stable_mir::mir::UnOp::Neg,
+    }
+}
+
+fn rustc_generator_to_generator(
+    generator: &rustc_hir::GeneratorKind,
+) -> stable_mir::mir::GeneratorKind {
+    use rustc_hir::{AsyncGeneratorKind, GeneratorKind};
+    match generator {
+        GeneratorKind::Async(async_gen) => {
+            let async_gen = match async_gen {
+                AsyncGeneratorKind::Block => stable_mir::mir::AsyncGeneratorKind::Block,
+                AsyncGeneratorKind::Closure => stable_mir::mir::AsyncGeneratorKind::Closure,
+                AsyncGeneratorKind::Fn => stable_mir::mir::AsyncGeneratorKind::Fn,
+            };
+            stable_mir::mir::GeneratorKind::Async(async_gen)
+        }
+        GeneratorKind::Gen => stable_mir::mir::GeneratorKind::Gen,
+    }
+}
+
 fn rustc_terminator_to_terminator(
     terminator: &rustc_middle::mir::Terminator<'_>,
 ) -> stable_mir::mir::Terminator {
@@ -176,7 +274,13 @@ fn rustc_terminator_to_terminator(
                 unwind: rustc_unwind_to_unwind(unwind),
             }
         }
-        Assert { .. } => todo!(),
+        Assert { cond, expected, msg, target, unwind } => Terminator::Assert {
+            cond: rustc_op_to_op(cond),
+            expected: *expected,
+            msg: rustc_assert_msg_to_msg(msg),
+            target: target.as_usize(),
+            unwind: rustc_unwind_to_unwind(unwind),
+        },
         Yield { .. } => todo!(),
         GeneratorDrop => todo!(),
         FalseEdge { .. } => todo!(),
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs
index b3d0a835733..699c9457381 100644
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs
@@ -38,9 +38,9 @@ pub enum Terminator {
     Assert {
         cond: Operand,
         expected: bool,
-        msg: String,
+        msg: AssertMessage,
         target: usize,
-        cleanup: Option<usize>,
+        unwind: UnwindAction,
     },
 }
 
@@ -53,11 +53,71 @@ pub enum UnwindAction {
 }
 
 #[derive(Clone, Debug)]
+pub enum AssertMessage {
+    BoundsCheck { len: Operand, index: Operand },
+    Overflow(BinOp, Operand, Operand),
+    OverflowNeg(Operand),
+    DivisionByZero(Operand),
+    RemainderByZero(Operand),
+    ResumedAfterReturn(GeneratorKind),
+    ResumedAfterPanic(GeneratorKind),
+    MisalignedPointerDereference { required: Operand, found: Operand },
+}
+
+#[derive(Clone, Debug)]
+pub enum BinOp {
+    Add,
+    Sub,
+    Mul,
+    Div,
+    Rem,
+    BitXor,
+    BitAnd,
+    BitOr,
+    Shl,
+    Shr,
+    Eq,
+    Lt,
+    Le,
+    Ne,
+    Ge,
+    Gt,
+    Offset,
+}
+
+#[derive(Clone, Debug)]
+pub enum UnOp {
+    Not,
+    Neg,
+}
+
+#[derive(Clone, Debug)]
+pub enum GeneratorKind {
+    Async(AsyncGeneratorKind),
+    Gen,
+}
+
+#[derive(Clone, Debug)]
+pub enum AsyncGeneratorKind {
+    Block,
+    Closure,
+    Fn,
+}
+
+#[derive(Clone, Debug)]
 pub enum Statement {
-    Assign(Place, Operand),
+    Assign(Place, Rvalue),
     Nop,
 }
 
+// FIXME this is incomplete
+#[derive(Clone, Debug)]
+pub enum Rvalue {
+    Use(Operand),
+    CheckedBinaryOp(BinOp, Operand, Operand),
+    UnaryOp(UnOp, Operand),
+}
+
 #[derive(Clone, Debug)]
 pub enum Operand {
     Copy(Place),
@@ -68,6 +128,7 @@ pub enum Operand {
 #[derive(Clone, Debug)]
 pub struct Place {
     pub local: usize,
+    pub projection: String,
 }
 
 #[derive(Clone, Debug)]
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index f89690e1d15..1454d6dde6c 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -69,6 +69,15 @@ fn test_stable_mir(tcx: TyCtxt<'_>) {
         stable_mir::mir::Terminator::Drop { .. } => {}
         other => panic!("{other:?}"),
     }
+
+    let assert = get_item(tcx, &items, (DefKind::Fn, "assert")).unwrap();
+    let body = assert.body();
+    assert_eq!(body.blocks.len(), 2);
+    let block = &body.blocks[0];
+    match &block.terminator {
+        stable_mir::mir::Terminator::Assert { .. } => {}
+        other => panic!("{other:?}"),
+    }
 }
 
 // Use internal API to find a function in a crate.
@@ -142,7 +151,11 @@ fn generate_input(path: &str) -> std::io::Result<()> {
         x_64.wrapping_add(y_64)
     }}
 
-    pub fn drop(_: String) {{}}"#
+    pub fn drop(_: String) {{}}
+
+    pub fn assert(x: i32) -> i32 {{
+        x + 1
+    }}"#
     )?;
     Ok(())
 }