Skip to content

Commit 3065925

Browse files
Rollup merge of rust-lang#138026 - celinval:chores-item-has-body, r=compiler-errors
Make CrateItem::body() function return an option When we initially created `CrateItem`, it would only represent items that contain a body. That is no longer the case, for now, make this explicit by expanding the APIs to retrieve the item body. This is related to rust-lang/project-stable-mir#34 r? `@oli-obk`
2 parents a69982e + 4d75c4f commit 3065925

File tree

7 files changed

+57
-47
lines changed

7 files changed

+57
-47
lines changed

Diff for: compiler/stable_mir/src/lib.rs

+16-5
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,21 @@ crate_def_with_ty! {
129129
}
130130

131131
impl CrateItem {
132-
/// This will return the body of an item.
133-
///
134-
/// This will panic if no body is available.
135-
pub fn body(&self) -> mir::Body {
132+
/// This will return the body of an item or panic if it's not available.
133+
pub fn expect_body(&self) -> mir::Body {
136134
with(|cx| cx.mir_body(self.0))
137135
}
138136

137+
/// Return the body of an item if available.
138+
pub fn body(&self) -> Option<mir::Body> {
139+
with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
140+
}
141+
142+
/// Check if a body is available for this item.
143+
pub fn has_body(&self) -> bool {
144+
with(|cx| cx.has_body(self.0))
145+
}
146+
139147
pub fn span(&self) -> Span {
140148
with(|cx| cx.span_of_an_item(self.0))
141149
}
@@ -156,8 +164,11 @@ impl CrateItem {
156164
with(|cx| cx.is_foreign_item(self.0))
157165
}
158166

167+
/// Emit MIR for this item body.
159168
pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
160-
self.body().dump(w, &self.name())
169+
self.body()
170+
.ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
171+
.dump(w, &self.name())
161172
}
162173
}
163174

Diff for: tests/ui-fulldeps/stable-mir/check_ty_fold.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ extern crate rustc_interface;
1818
extern crate stable_mir;
1919

2020
use rustc_smir::rustc_internal;
21-
use stable_mir::ty::{RigidTy, TyKind, Ty, };
22-
use stable_mir::mir::{Body, MirVisitor, FieldIdx, Place, ProjectionElem, visit::{Location,
23-
PlaceContext}};
21+
use stable_mir::mir::{
22+
Body, FieldIdx, MirVisitor, Place, ProjectionElem,
23+
visit::{Location, PlaceContext},
24+
};
25+
use stable_mir::ty::{RigidTy, Ty, TyKind};
2426
use std::io::Write;
2527
use std::ops::ControlFlow;
2628

@@ -29,8 +31,8 @@ const CRATE_NAME: &str = "input";
2931
/// This function uses the Stable MIR APIs to get information about the test crate.
3032
fn test_stable_mir() -> ControlFlow<()> {
3133
let main_fn = stable_mir::entry_fn();
32-
let body = main_fn.unwrap().body();
33-
let mut visitor = PlaceVisitor{ body: &body, tested: false};
34+
let body = main_fn.unwrap().expect_body();
35+
let mut visitor = PlaceVisitor { body: &body, tested: false };
3436
visitor.visit_body(&body);
3537
assert!(visitor.tested);
3638
ControlFlow::Continue(())

Diff for: tests/ui-fulldeps/stable-mir/crate-info.rs

+13-10
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ fn test_stable_mir() -> ControlFlow<()> {
4545
assert!(stable_mir::find_crates("std").len() == 1);
4646

4747
let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap();
48-
let body = bar.body();
48+
let body = bar.expect_body();
4949
assert_eq!(body.locals().len(), 2);
5050
assert_eq!(body.blocks.len(), 1);
5151
let block = &body.blocks[0];
@@ -60,7 +60,7 @@ fn test_stable_mir() -> ControlFlow<()> {
6060
}
6161

6262
let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap();
63-
let body = foo_bar.body();
63+
let body = foo_bar.expect_body();
6464
assert_eq!(body.locals().len(), 5);
6565
assert_eq!(body.blocks.len(), 4);
6666
let block = &body.blocks[0];
@@ -70,7 +70,7 @@ fn test_stable_mir() -> ControlFlow<()> {
7070
}
7171

7272
let types = get_item(&items, (DefKind::Fn, "types")).unwrap();
73-
let body = types.body();
73+
let body = types.expect_body();
7474
assert_eq!(body.locals().len(), 6);
7575
assert_matches!(
7676
body.locals()[0].ty.kind(),
@@ -100,7 +100,7 @@ fn test_stable_mir() -> ControlFlow<()> {
100100
);
101101

102102
let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap();
103-
let body = drop.body();
103+
let body = drop.expect_body();
104104
assert_eq!(body.blocks.len(), 2);
105105
let block = &body.blocks[0];
106106
match &block.terminator.kind {
@@ -109,7 +109,7 @@ fn test_stable_mir() -> ControlFlow<()> {
109109
}
110110

111111
let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap();
112-
let body = assert.body();
112+
let body = assert.expect_body();
113113
assert_eq!(body.blocks.len(), 2);
114114
let block = &body.blocks[0];
115115
match &block.terminator.kind {
@@ -123,7 +123,8 @@ fn test_stable_mir() -> ControlFlow<()> {
123123
match &block.terminator.kind {
124124
stable_mir::mir::TerminatorKind::Call { func, .. } => {
125125
let TyKind::RigidTy(ty) = func.ty(&body.locals()).unwrap().kind() else {
126-
unreachable!() };
126+
unreachable!()
127+
};
127128
let RigidTy::FnDef(def, args) = ty else { unreachable!() };
128129
let next_func = Instance::resolve(def, &args).unwrap();
129130
match next_func.body().unwrap().locals()[1].ty.kind() {
@@ -138,10 +139,10 @@ fn test_stable_mir() -> ControlFlow<()> {
138139

139140
let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap();
140141
// Ensure we don't panic trying to get the body of a constant.
141-
foo_const.body();
142+
foo_const.expect_body();
142143

143144
let locals_fn = get_item(&items, (DefKind::Fn, "locals")).unwrap();
144-
let body = locals_fn.body();
145+
let body = locals_fn.expect_body();
145146
assert_eq!(body.locals().len(), 4);
146147
assert_matches!(
147148
body.ret_local().ty.kind(),
@@ -172,8 +173,10 @@ fn get_item<'a>(
172173
item: (DefKind, &str),
173174
) -> Option<&'a stable_mir::CrateItem> {
174175
items.iter().find(|crate_item| {
175-
matches!((item.0, crate_item.kind()), (DefKind::Fn, ItemKind::Fn) | (DefKind::Const,
176-
ItemKind::Const)) && crate_item.name() == item.1
176+
matches!(
177+
(item.0, crate_item.kind()),
178+
(DefKind::Fn, ItemKind::Fn) | (DefKind::Const, ItemKind::Const)
179+
) && crate_item.name() == item.1
177180
})
178181
}
179182

Diff for: tests/ui-fulldeps/stable-mir/projections.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ extern crate rustc_interface;
1818
extern crate stable_mir;
1919

2020
use rustc_smir::rustc_internal;
21+
use stable_mir::ItemKind;
2122
use stable_mir::crate_def::CrateDef;
2223
use stable_mir::mir::{ProjectionElem, Rvalue, StatementKind};
2324
use stable_mir::ty::{RigidTy, TyKind, UintTy};
24-
use stable_mir::ItemKind;
2525
use std::assert_matches::assert_matches;
2626
use std::io::Write;
2727
use std::ops::ControlFlow;
@@ -31,7 +31,7 @@ const CRATE_NAME: &str = "input";
3131
/// Tests projections within Place objects
3232
fn test_place_projections() -> ControlFlow<()> {
3333
let items = stable_mir::all_local_items();
34-
let body = get_item(&items, (ItemKind::Fn, "projections")).unwrap().body();
34+
let body = get_item(&items, (ItemKind::Fn, "projections")).unwrap().expect_body();
3535
assert_eq!(body.blocks.len(), 4);
3636
// The first statement assigns `&s.c` to a local. The projections include a deref for `s`, since
3737
// `s` is passed as a reference argument, and a field access for field `c`.
@@ -53,7 +53,7 @@ fn test_place_projections() -> ControlFlow<()> {
5353
);
5454
let ty = place.ty(body.locals()).unwrap();
5555
assert_matches!(ty.kind().rigid(), Some(RigidTy::Ref(..)));
56-
},
56+
}
5757
other => panic!(
5858
"Unable to match against expected rvalue projection. Expected the projection \
5959
for `s.c`, which is a Deref and u8 Field. Got: {:?}",
@@ -137,9 +137,7 @@ fn get_item<'a>(
137137
items: &'a stable_mir::CrateItems,
138138
item: (ItemKind, &str),
139139
) -> Option<&'a stable_mir::CrateItem> {
140-
items.iter().find(|crate_item| {
141-
crate_item.kind() == item.0 && crate_item.name() == item.1
142-
})
140+
items.iter().find(|crate_item| crate_item.kind() == item.0 && crate_item.name() == item.1)
143141
}
144142

145143
/// This test will generate and analyze a dummy crate using the stable mir.

Diff for: tests/ui-fulldeps/stable-mir/smir_internal.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const CRATE_NAME: &str = "input";
2626

2727
fn test_translation(tcx: TyCtxt<'_>) -> ControlFlow<()> {
2828
let main_fn = stable_mir::entry_fn().unwrap();
29-
let body = main_fn.body();
29+
let body = main_fn.expect_body();
3030
let orig_ty = body.locals()[0].ty;
3131
let rustc_ty = rustc_internal::internal(tcx, &orig_ty);
3232
assert!(rustc_ty.is_unit());

Diff for: tests/ui-fulldeps/stable-mir/smir_serde.rs

+10-14
Original file line numberDiff line numberDiff line change
@@ -14,33 +14,29 @@ extern crate rustc_smir;
1414
extern crate rustc_driver;
1515
extern crate rustc_interface;
1616
extern crate rustc_middle;
17-
extern crate stable_mir;
1817
extern crate serde;
1918
extern crate serde_json;
19+
extern crate stable_mir;
2020

2121
use rustc_middle::ty::TyCtxt;
2222
use rustc_smir::rustc_internal;
23+
use serde_json::to_string;
2324
use stable_mir::mir::Body;
24-
use std::io::{Write, BufWriter};
25+
use std::io::{BufWriter, Write};
2526
use std::ops::ControlFlow;
26-
use serde_json::to_string;
27-
2827

2928
const CRATE_NAME: &str = "input";
3029

3130
fn serialize_to_json(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
3231
let path = "output.json";
33-
let mut writer = BufWriter::new(std::fs::File::create(path)
34-
.expect("Failed to create path"));
32+
let mut writer = BufWriter::new(std::fs::File::create(path).expect("Failed to create path"));
3533
let local_crate = stable_mir::local_crate();
36-
let items: Vec<Body> = stable_mir::all_local_items()
37-
.iter()
38-
.map(|item| { item.body() })
39-
.collect();
40-
let crate_data = ( local_crate.name, items );
41-
writer.write_all(to_string(&crate_data)
42-
.expect("serde_json failed")
43-
.as_bytes()).expect("JSON serialization failed");
34+
let items: Vec<Body> =
35+
stable_mir::all_local_items().iter().map(|item| item.expect_body()).collect();
36+
let crate_data = (local_crate.name, items);
37+
writer
38+
.write_all(to_string(&crate_data).expect("serde_json failed").as_bytes())
39+
.expect("JSON serialization failed");
4440
ControlFlow::Continue(())
4541
}
4642

Diff for: tests/ui-fulldeps/stable-mir/smir_visitor.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ extern crate rustc_driver;
1616
extern crate rustc_interface;
1717
extern crate stable_mir;
1818

19-
use std::collections::HashSet;
2019
use rustc_smir::rustc_internal;
21-
use stable_mir::*;
2220
use stable_mir::mir::MirVisitor;
21+
use stable_mir::*;
22+
use std::collections::HashSet;
2323
use std::io::Write;
2424
use std::ops::ControlFlow;
2525

2626
const CRATE_NAME: &str = "input";
2727

2828
fn test_visitor() -> ControlFlow<()> {
2929
let main_fn = stable_mir::entry_fn();
30-
let main_body = main_fn.unwrap().body();
30+
let main_body = main_fn.unwrap().expect_body();
3131
let main_visitor = TestVisitor::collect(&main_body);
3232
assert!(main_visitor.ret_val.is_some());
3333
assert!(main_visitor.args.is_empty());
@@ -51,7 +51,7 @@ struct TestVisitor<'a> {
5151
pub tys: HashSet<ty::Ty>,
5252
pub ret_val: Option<mir::LocalDecl>,
5353
pub args: Vec<mir::LocalDecl>,
54-
pub calls: Vec<mir::mono::Instance>
54+
pub calls: Vec<mir::mono::Instance>,
5555
}
5656

5757
impl<'a> TestVisitor<'a> {
@@ -90,8 +90,8 @@ impl<'a> mir::MirVisitor for TestVisitor<'a> {
9090
fn visit_terminator(&mut self, term: &mir::Terminator, location: mir::visit::Location) {
9191
if let mir::TerminatorKind::Call { func, .. } = &term.kind {
9292
let ty::TyKind::RigidTy(ty) = func.ty(self.body.locals()).unwrap().kind() else {
93-
unreachable!
94-
() };
93+
unreachable!()
94+
};
9595
let ty::RigidTy::FnDef(def, args) = ty else { unreachable!() };
9696
self.calls.push(mir::mono::Instance::resolve(def, &args).unwrap());
9797
}

0 commit comments

Comments
 (0)