@@ -23,12 +23,15 @@ extern crate stable_mir;
23
23
24
24
use rustc_middle:: ty:: TyCtxt ;
25
25
use rustc_smir:: rustc_internal;
26
- use stable_mir:: { CrateItem , CrateItems , ItemKind } ;
27
26
use stable_mir:: crate_def:: CrateDef ;
28
27
use stable_mir:: mir:: alloc:: GlobalAlloc ;
29
- use stable_mir:: mir:: mono:: StaticDef ;
28
+ use stable_mir:: mir:: mono:: { Instance , StaticDef } ;
29
+ use stable_mir:: mir:: Body ;
30
+ use stable_mir:: ty:: { Allocation , ConstantKind } ;
31
+ use stable_mir:: { CrateItem , CrateItems , ItemKind } ;
30
32
use std:: ascii:: Char ;
31
33
use std:: assert_matches:: assert_matches;
34
+ use std:: collections:: HashMap ;
32
35
use std:: io:: Write ;
33
36
use std:: ops:: ControlFlow ;
34
37
@@ -41,6 +44,7 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
41
44
check_foo ( * get_item ( & items, ( ItemKind :: Static , "FOO" ) ) . unwrap ( ) ) ;
42
45
check_bar ( * get_item ( & items, ( ItemKind :: Static , "BAR" ) ) . unwrap ( ) ) ;
43
46
check_len ( * get_item ( & items, ( ItemKind :: Static , "LEN" ) ) . unwrap ( ) ) ;
47
+ check_other_consts ( * get_item ( & items, ( ItemKind :: Fn , "other_consts" ) ) . unwrap ( ) ) ;
44
48
ControlFlow :: Continue ( ( ) )
45
49
}
46
50
@@ -80,6 +84,66 @@ fn check_bar(item: CrateItem) {
80
84
assert_eq ! ( std:: str :: from_utf8( & allocation. raw_bytes( ) . unwrap( ) ) , Ok ( "Bar" ) ) ;
81
85
}
82
86
87
+ /// Check the allocation data for constants used in `other_consts` function.
88
+ fn check_other_consts ( item : CrateItem ) {
89
+ // Instance body will force constant evaluation.
90
+ let body = Instance :: try_from ( item) . unwrap ( ) . body ( ) . unwrap ( ) ;
91
+ let assigns = collect_consts ( & body) ;
92
+ assert_eq ! ( assigns. len( ) , 8 ) ;
93
+ for ( name, alloc) in assigns {
94
+ match name. as_str ( ) {
95
+ "_max_u128" => {
96
+ assert_eq ! ( alloc. read_uint( ) , Ok ( u128 :: MAX ) , "Failed parsing allocation: {alloc:?}" )
97
+ }
98
+ "_min_i128" => {
99
+ assert_eq ! ( alloc. read_int( ) , Ok ( i128 :: MIN ) , "Failed parsing allocation: {alloc:?}" )
100
+ }
101
+ "_max_i8" => {
102
+ assert_eq ! (
103
+ alloc. read_int( ) . unwrap( ) as i8 ,
104
+ i8 :: MAX ,
105
+ "Failed parsing allocation: {alloc:?}"
106
+ )
107
+ }
108
+ "_char" => {
109
+ assert_eq ! (
110
+ char :: from_u32( alloc. read_uint( ) . unwrap( ) as u32 ) ,
111
+ Some ( 'x' ) ,
112
+ "Failed parsing allocation: {alloc:?}"
113
+ )
114
+ }
115
+ "_false" => {
116
+ assert_eq ! ( alloc. read_bool( ) , Ok ( false ) , "Failed parsing allocation: {alloc:?}" )
117
+ }
118
+ "_true" => {
119
+ assert_eq ! ( alloc. read_bool( ) , Ok ( true ) , "Failed parsing allocation: {alloc:?}" )
120
+ }
121
+ "_ptr" => {
122
+ assert_eq ! ( alloc. is_null( ) , Ok ( false ) , "Failed parsing allocation: {alloc:?}" )
123
+ }
124
+ "_null_ptr" => {
125
+ assert_eq ! ( alloc. is_null( ) , Ok ( true ) , "Failed parsing allocation: {alloc:?}" )
126
+ }
127
+ _ => {
128
+ unreachable ! ( "{name}" )
129
+ }
130
+ }
131
+ }
132
+ }
133
+
134
+ /// Collects all the constant assignments.
135
+ pub fn collect_consts ( body : & Body ) -> HashMap < String , & Allocation > {
136
+ body. var_debug_info
137
+ . iter ( )
138
+ . filter_map ( |info| {
139
+ info. constant ( ) . map ( |const_op| {
140
+ let ConstantKind :: Allocated ( alloc) = const_op. const_ . kind ( ) else { unreachable ! ( ) } ;
141
+ ( info. name . clone ( ) , alloc)
142
+ } )
143
+ } )
144
+ . collect :: < HashMap < _ , _ > > ( )
145
+ }
146
+
83
147
/// Check the allocation data for `LEN`.
84
148
///
85
149
/// ```no_run
@@ -97,9 +161,7 @@ fn get_item<'a>(
97
161
items : & ' a CrateItems ,
98
162
item : ( ItemKind , & str ) ,
99
163
) -> Option < & ' a stable_mir:: CrateItem > {
100
- items. iter ( ) . find ( |crate_item| {
101
- ( item. 0 == crate_item. kind ( ) ) && crate_item. name ( ) == item. 1
102
- } )
164
+ items. iter ( ) . find ( |crate_item| ( item. 0 == crate_item. kind ( ) ) && crate_item. name ( ) == item. 1 )
103
165
}
104
166
105
167
/// This test will generate and analyze a dummy crate using the stable mir.
@@ -126,10 +188,23 @@ fn generate_input(path: &str) -> std::io::Result<()> {
126
188
static LEN: usize = 2;
127
189
static FOO: [&str; 2] = ["hi", "there"];
128
190
static BAR: &str = "Bar";
191
+ const NULL: *const u8 = std::ptr::null();
192
+
193
+ fn other_consts() {{
194
+ let _max_u128 = u128::MAX;
195
+ let _min_i128 = i128::MIN;
196
+ let _max_i8 = i8::MAX;
197
+ let _char = 'x';
198
+ let _false = false;
199
+ let _true = true;
200
+ let _ptr = &BAR;
201
+ let _null_ptr: *const u8 = NULL;
202
+ }}
129
203
130
204
pub fn main() {{
131
205
println!("{{FOO:?}}! {{BAR}}");
132
206
assert_eq!(FOO.len(), LEN);
207
+ other_consts();
133
208
}}"#
134
209
) ?;
135
210
Ok ( ( ) )
0 commit comments