@@ -23,12 +23,15 @@ extern crate stable_mir;
2323
2424use rustc_middle:: ty:: TyCtxt ;
2525use rustc_smir:: rustc_internal;
26- use stable_mir:: { CrateItem , CrateItems , ItemKind } ;
2726use stable_mir:: crate_def:: CrateDef ;
2827use 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 } ;
3032use std:: ascii:: Char ;
3133use std:: assert_matches:: assert_matches;
34+ use std:: collections:: HashMap ;
3235use std:: io:: Write ;
3336use std:: ops:: ControlFlow ;
3437
@@ -41,6 +44,7 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
4144 check_foo ( * get_item ( & items, ( ItemKind :: Static , "FOO" ) ) . unwrap ( ) ) ;
4245 check_bar ( * get_item ( & items, ( ItemKind :: Static , "BAR" ) ) . unwrap ( ) ) ;
4346 check_len ( * get_item ( & items, ( ItemKind :: Static , "LEN" ) ) . unwrap ( ) ) ;
47+ check_other_consts ( * get_item ( & items, ( ItemKind :: Fn , "other_consts" ) ) . unwrap ( ) ) ;
4448 ControlFlow :: Continue ( ( ) )
4549}
4650
@@ -80,6 +84,66 @@ fn check_bar(item: CrateItem) {
8084 assert_eq ! ( std:: str :: from_utf8( & allocation. raw_bytes( ) . unwrap( ) ) , Ok ( "Bar" ) ) ;
8185}
8286
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+
83147/// Check the allocation data for `LEN`.
84148///
85149/// ```no_run
@@ -97,9 +161,7 @@ fn get_item<'a>(
97161 items : & ' a CrateItems ,
98162 item : ( ItemKind , & str ) ,
99163) -> 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 )
103165}
104166
105167/// 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<()> {
126188 static LEN: usize = 2;
127189 static FOO: [&str; 2] = ["hi", "there"];
128190 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+ }}
129203
130204 pub fn main() {{
131205 println!("{{FOO:?}}! {{BAR}}");
132206 assert_eq!(FOO.len(), LEN);
207+ other_consts();
133208 }}"#
134209 ) ?;
135210 Ok ( ( ) )
0 commit comments