1+ //@ run-pass
2+ //! Tests stable mir API for retrieving the body of a generic 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+ }
0 commit comments