diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index 8df36e23c4a..70d42dfbfcb 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -129,13 +129,21 @@ crate_def_with_ty! {
 }
 
 impl CrateItem {
-    /// This will return the body of an item.
-    ///
-    /// This will panic if no body is available.
-    pub fn body(&self) -> mir::Body {
+    /// This will return the body of an item or panic if it's not available.
+    pub fn expect_body(&self) -> mir::Body {
         with(|cx| cx.mir_body(self.0))
     }
 
+    /// Return the body of an item if available.
+    pub fn body(&self) -> Option<mir::Body> {
+        with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
+    }
+
+    /// Check if a body is available for this item.
+    pub fn has_body(&self) -> bool {
+        with(|cx| cx.has_body(self.0))
+    }
+
     pub fn span(&self) -> Span {
         with(|cx| cx.span_of_an_item(self.0))
     }
@@ -156,8 +164,11 @@ impl CrateItem {
         with(|cx| cx.is_foreign_item(self.0))
     }
 
+    /// Emit MIR for this item body.
     pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
-        self.body().dump(w, &self.name())
+        self.body()
+            .ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
+            .dump(w, &self.name())
     }
 }
 
diff --git a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
index 9fa4929d68e..9d71697178e 100644
--- a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
+++ b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
@@ -18,9 +18,11 @@ extern crate rustc_interface;
 extern crate stable_mir;
 
 use rustc_smir::rustc_internal;
-use stable_mir::ty::{RigidTy, TyKind, Ty, };
-use stable_mir::mir::{Body, MirVisitor, FieldIdx, Place, ProjectionElem, visit::{Location,
-                                                                            PlaceContext}};
+use stable_mir::mir::{
+    Body, FieldIdx, MirVisitor, Place, ProjectionElem,
+    visit::{Location, PlaceContext},
+};
+use stable_mir::ty::{RigidTy, Ty, TyKind};
 use std::io::Write;
 use std::ops::ControlFlow;
 
@@ -29,8 +31,8 @@ const CRATE_NAME: &str = "input";
 /// This function uses the Stable MIR APIs to get information about the test crate.
 fn test_stable_mir() -> ControlFlow<()> {
     let main_fn = stable_mir::entry_fn();
-    let body = main_fn.unwrap().body();
-    let mut visitor = PlaceVisitor{ body: &body, tested: false};
+    let body = main_fn.unwrap().expect_body();
+    let mut visitor = PlaceVisitor { body: &body, tested: false };
     visitor.visit_body(&body);
     assert!(visitor.tested);
     ControlFlow::Continue(())
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 7f0e9b50335..4d2d7e26276 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -45,7 +45,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     assert!(stable_mir::find_crates("std").len() == 1);
 
     let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap();
-    let body = bar.body();
+    let body = bar.expect_body();
     assert_eq!(body.locals().len(), 2);
     assert_eq!(body.blocks.len(), 1);
     let block = &body.blocks[0];
@@ -60,7 +60,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     }
 
     let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap();
-    let body = foo_bar.body();
+    let body = foo_bar.expect_body();
     assert_eq!(body.locals().len(), 5);
     assert_eq!(body.blocks.len(), 4);
     let block = &body.blocks[0];
@@ -70,7 +70,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     }
 
     let types = get_item(&items, (DefKind::Fn, "types")).unwrap();
-    let body = types.body();
+    let body = types.expect_body();
     assert_eq!(body.locals().len(), 6);
     assert_matches!(
         body.locals()[0].ty.kind(),
@@ -100,7 +100,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     );
 
     let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap();
-    let body = drop.body();
+    let body = drop.expect_body();
     assert_eq!(body.blocks.len(), 2);
     let block = &body.blocks[0];
     match &block.terminator.kind {
@@ -109,7 +109,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     }
 
     let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap();
-    let body = assert.body();
+    let body = assert.expect_body();
     assert_eq!(body.blocks.len(), 2);
     let block = &body.blocks[0];
     match &block.terminator.kind {
@@ -123,7 +123,8 @@ fn test_stable_mir() -> ControlFlow<()> {
         match &block.terminator.kind {
             stable_mir::mir::TerminatorKind::Call { func, .. } => {
                 let TyKind::RigidTy(ty) = func.ty(&body.locals()).unwrap().kind() else {
-                    unreachable!() };
+                    unreachable!()
+                };
                 let RigidTy::FnDef(def, args) = ty else { unreachable!() };
                 let next_func = Instance::resolve(def, &args).unwrap();
                 match next_func.body().unwrap().locals()[1].ty.kind() {
@@ -138,10 +139,10 @@ fn test_stable_mir() -> ControlFlow<()> {
 
     let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap();
     // Ensure we don't panic trying to get the body of a constant.
-    foo_const.body();
+    foo_const.expect_body();
 
     let locals_fn = get_item(&items, (DefKind::Fn, "locals")).unwrap();
-    let body = locals_fn.body();
+    let body = locals_fn.expect_body();
     assert_eq!(body.locals().len(), 4);
     assert_matches!(
         body.ret_local().ty.kind(),
@@ -172,8 +173,10 @@ fn get_item<'a>(
     item: (DefKind, &str),
 ) -> Option<&'a stable_mir::CrateItem> {
     items.iter().find(|crate_item| {
-        matches!((item.0, crate_item.kind()), (DefKind::Fn, ItemKind::Fn) | (DefKind::Const,
-            ItemKind::Const)) && crate_item.name() == item.1
+        matches!(
+            (item.0, crate_item.kind()),
+            (DefKind::Fn, ItemKind::Fn) | (DefKind::Const, ItemKind::Const)
+        ) && crate_item.name() == item.1
     })
 }
 
diff --git a/tests/ui-fulldeps/stable-mir/projections.rs b/tests/ui-fulldeps/stable-mir/projections.rs
index 3cc71247e67..6f82eba61fc 100644
--- a/tests/ui-fulldeps/stable-mir/projections.rs
+++ b/tests/ui-fulldeps/stable-mir/projections.rs
@@ -18,10 +18,10 @@ extern crate rustc_interface;
 extern crate stable_mir;
 
 use rustc_smir::rustc_internal;
+use stable_mir::ItemKind;
 use stable_mir::crate_def::CrateDef;
 use stable_mir::mir::{ProjectionElem, Rvalue, StatementKind};
 use stable_mir::ty::{RigidTy, TyKind, UintTy};
-use stable_mir::ItemKind;
 use std::assert_matches::assert_matches;
 use std::io::Write;
 use std::ops::ControlFlow;
@@ -31,7 +31,7 @@ const CRATE_NAME: &str = "input";
 /// Tests projections within Place objects
 fn test_place_projections() -> ControlFlow<()> {
     let items = stable_mir::all_local_items();
-    let body = get_item(&items, (ItemKind::Fn, "projections")).unwrap().body();
+    let body = get_item(&items, (ItemKind::Fn, "projections")).unwrap().expect_body();
     assert_eq!(body.blocks.len(), 4);
     // The first statement assigns `&s.c` to a local. The projections include a deref for `s`, since
     // `s` is passed as a reference argument, and a field access for field `c`.
@@ -53,7 +53,7 @@ fn test_place_projections() -> ControlFlow<()> {
                     );
                     let ty = place.ty(body.locals()).unwrap();
                     assert_matches!(ty.kind().rigid(), Some(RigidTy::Ref(..)));
-                },
+                }
                 other => panic!(
                     "Unable to match against expected rvalue projection. Expected the projection \
                      for `s.c`, which is a Deref and u8 Field. Got: {:?}",
@@ -137,9 +137,7 @@ fn get_item<'a>(
     items: &'a stable_mir::CrateItems,
     item: (ItemKind, &str),
 ) -> Option<&'a stable_mir::CrateItem> {
-    items.iter().find(|crate_item| {
-        crate_item.kind() == item.0 && crate_item.name() == item.1
-    })
+    items.iter().find(|crate_item| crate_item.kind() == item.0 && crate_item.name() == item.1)
 }
 
 /// This test will generate and analyze a dummy crate using the stable mir.
diff --git a/tests/ui-fulldeps/stable-mir/smir_internal.rs b/tests/ui-fulldeps/stable-mir/smir_internal.rs
index 453e5372de4..f9972dc27e3 100644
--- a/tests/ui-fulldeps/stable-mir/smir_internal.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_internal.rs
@@ -26,7 +26,7 @@ const CRATE_NAME: &str = "input";
 
 fn test_translation(tcx: TyCtxt<'_>) -> ControlFlow<()> {
     let main_fn = stable_mir::entry_fn().unwrap();
-    let body = main_fn.body();
+    let body = main_fn.expect_body();
     let orig_ty = body.locals()[0].ty;
     let rustc_ty = rustc_internal::internal(tcx, &orig_ty);
     assert!(rustc_ty.is_unit());
diff --git a/tests/ui-fulldeps/stable-mir/smir_serde.rs b/tests/ui-fulldeps/stable-mir/smir_serde.rs
index 2c74276d550..9b3638a9f2f 100644
--- a/tests/ui-fulldeps/stable-mir/smir_serde.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_serde.rs
@@ -14,33 +14,29 @@ extern crate rustc_smir;
 extern crate rustc_driver;
 extern crate rustc_interface;
 extern crate rustc_middle;
-extern crate stable_mir;
 extern crate serde;
 extern crate serde_json;
+extern crate stable_mir;
 
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
-use stable_mir::mir::Body;
-use std::io::{Write, BufWriter};
-use std::ops::ControlFlow;
 use serde_json::to_string;
-
+use stable_mir::mir::Body;
+use std::io::{BufWriter, Write};
+use std::ops::ControlFlow;
 
 const CRATE_NAME: &str = "input";
 
 fn serialize_to_json(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
     let path = "output.json";
-    let mut writer = BufWriter::new(std::fs::File::create(path)
-        .expect("Failed to create path"));
+    let mut writer = BufWriter::new(std::fs::File::create(path).expect("Failed to create path"));
     let local_crate = stable_mir::local_crate();
-    let items: Vec<Body> = stable_mir::all_local_items()
-        .iter()
-        .map(|item| { item.body() })
-        .collect();
-    let crate_data = ( local_crate.name, items );
-    writer.write_all(to_string(&crate_data)
-        .expect("serde_json failed")
-        .as_bytes()).expect("JSON serialization failed");
+    let items: Vec<Body> =
+        stable_mir::all_local_items().iter().map(|item| item.expect_body()).collect();
+    let crate_data = (local_crate.name, items);
+    writer
+        .write_all(to_string(&crate_data).expect("serde_json failed").as_bytes())
+        .expect("JSON serialization failed");
     ControlFlow::Continue(())
 }
 
diff --git a/tests/ui-fulldeps/stable-mir/smir_visitor.rs b/tests/ui-fulldeps/stable-mir/smir_visitor.rs
index 0a6415d490e..cffb41742b4 100644
--- a/tests/ui-fulldeps/stable-mir/smir_visitor.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_visitor.rs
@@ -16,10 +16,10 @@ extern crate rustc_driver;
 extern crate rustc_interface;
 extern crate stable_mir;
 
-use std::collections::HashSet;
 use rustc_smir::rustc_internal;
-use stable_mir::*;
 use stable_mir::mir::MirVisitor;
+use stable_mir::*;
+use std::collections::HashSet;
 use std::io::Write;
 use std::ops::ControlFlow;
 
@@ -27,7 +27,7 @@ const CRATE_NAME: &str = "input";
 
 fn test_visitor() -> ControlFlow<()> {
     let main_fn = stable_mir::entry_fn();
-    let main_body = main_fn.unwrap().body();
+    let main_body = main_fn.unwrap().expect_body();
     let main_visitor = TestVisitor::collect(&main_body);
     assert!(main_visitor.ret_val.is_some());
     assert!(main_visitor.args.is_empty());
@@ -51,7 +51,7 @@ struct TestVisitor<'a> {
     pub tys: HashSet<ty::Ty>,
     pub ret_val: Option<mir::LocalDecl>,
     pub args: Vec<mir::LocalDecl>,
-    pub calls: Vec<mir::mono::Instance>
+    pub calls: Vec<mir::mono::Instance>,
 }
 
 impl<'a> TestVisitor<'a> {
@@ -90,8 +90,8 @@ impl<'a> mir::MirVisitor for TestVisitor<'a> {
     fn visit_terminator(&mut self, term: &mir::Terminator, location: mir::visit::Location) {
         if let mir::TerminatorKind::Call { func, .. } = &term.kind {
             let ty::TyKind::RigidTy(ty) = func.ty(self.body.locals()).unwrap().kind() else {
-                unreachable!
-            () };
+                unreachable!()
+            };
             let ty::RigidTy::FnDef(def, args) = ty else { unreachable!() };
             self.calls.push(mir::mono::Instance::resolve(def, &args).unwrap());
         }