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