Skip to content

Commit 1d66e66

Browse files
committed
add body to ClosureDef
1 parent 2398bd6 commit 1d66e66

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

compiler/rustc_smir/src/stable_mir/ty.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -742,6 +742,12 @@ crate_def! {
742742
pub ClosureDef;
743743
}
744744

745+
impl ClosureDef {
746+
pub fn body(&self) -> Option<Body> {
747+
with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
748+
}
749+
}
750+
745751
crate_def! {
746752
#[derive(Serialize)]
747753
pub CoroutineDef;
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
//@ run-pass
2+
//! Tests stable mir API for retrieving the body of a closure.
3+
4+
//@ ignore-stage1
5+
//@ ignore-cross-compile
6+
//@ ignore-remote
7+
//@ edition: 2021
8+
9+
#![feature(rustc_private)]
10+
#![feature(assert_matches)]
11+
12+
extern crate rustc_middle;
13+
#[macro_use]
14+
extern crate rustc_smir;
15+
extern crate rustc_driver;
16+
extern crate rustc_interface;
17+
extern crate stable_mir;
18+
19+
use std::io::Write;
20+
use std::ops::ControlFlow;
21+
22+
use stable_mir::mir::{Body, ConstOperand, Operand, TerminatorKind};
23+
use stable_mir::ty::{FnDef, RigidTy, TyKind};
24+
25+
const CRATE_NAME: &str = "crate_closure_body";
26+
27+
fn test_closure_body() -> ControlFlow<()> {
28+
let crate_items = stable_mir::all_local_items();
29+
for item in crate_items {
30+
let item_ty = item.ty();
31+
match &item_ty.kind() {
32+
TyKind::RigidTy(RigidTy::Closure(closure_def, _)) => {
33+
let closure_body = closure_def.body().unwrap();
34+
check_incr_closure_body(closure_body);
35+
}
36+
_ => {}
37+
}
38+
}
39+
40+
ControlFlow::Continue(())
41+
}
42+
43+
fn check_incr_closure_body(body: Body) {
44+
let first_block = &body.blocks[0];
45+
let TerminatorKind::Call { func: Operand::Constant(ConstOperand { const_, .. }), .. } =
46+
&first_block.terminator.kind
47+
else {
48+
panic!("expected Call Terminator, got: ");
49+
};
50+
51+
let TyKind::RigidTy(RigidTy::FnDef(FnDef(def_id), ..), ..) = const_.ty().kind() else {
52+
panic!("expected FnDef");
53+
};
54+
55+
assert_eq!(def_id.name(), "incr");
56+
}
57+
58+
fn main() {
59+
let path = "closure_body.rs";
60+
generate_input(&path).unwrap();
61+
let args = &[
62+
"rustc".to_string(),
63+
"-Cpanic=abort".to_string(),
64+
"--crate-name".to_string(),
65+
CRATE_NAME.to_string(),
66+
path.to_string(),
67+
];
68+
run!(args, test_closure_body).unwrap();
69+
}
70+
71+
fn generate_input(path: &str) -> std::io::Result<()> {
72+
let mut file = std::fs::File::create(path)?;
73+
write!(
74+
file,
75+
r#"
76+
fn incr(y: i32) -> i32 {{
77+
y + 1
78+
}}
79+
80+
fn main() {{
81+
let cl_incr = |x: i32| {{
82+
incr(x)
83+
}};
84+
85+
let _= cl_incr(5);
86+
}}
87+
"#
88+
)?;
89+
Ok(())
90+
}

0 commit comments

Comments
 (0)