Skip to content

Commit 18907ce

Browse files
authored
Unrolled build for #141307
Rollup merge of #141307 - b-naber:closure-body, r=celinval Add method to retrieve body of closure in stable-mir fixes rust-lang/project-stable-mir#85 r? `@celinval`
2 parents 1434630 + 8604e58 commit 18907ce

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

compiler/rustc_smir/src/stable_mir/ty.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,14 @@ crate_def! {
743743
pub ClosureDef;
744744
}
745745

746+
impl ClosureDef {
747+
/// Retrieves the body of the closure definition. Returns None if the body
748+
/// isn't available.
749+
pub fn body(&self) -> Option<Body> {
750+
with(|ctx| ctx.has_body(self.0).then(|| ctx.mir_body(self.0)))
751+
}
752+
}
753+
746754
crate_def! {
747755
#[derive(Serialize)]
748756
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(), "id");
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 id<T>(y: T) -> T {{
77+
y
78+
}}
79+
80+
fn main() {{
81+
let cl_id= |x| {{
82+
id(x)
83+
}};
84+
85+
let _= cl_id(5);
86+
}}
87+
"#
88+
)?;
89+
Ok(())
90+
}
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)