rust/tests/ui-fulldeps/stable-mir/check_def_ty.rs
2024-09-25 19:00:19 -07:00

114 lines
3.3 KiB
Rust

//@ run-pass
//! Test that users are able to use stable mir APIs to retrieve type information from a crate item
//! definition.
//@ ignore-stage1
//@ ignore-cross-compile
//@ ignore-remote
//@ ignore-windows-gnu mingw has troubles with linking https://github.com/rust-lang/rust/pull/116837
//@ edition: 2021
#![feature(rustc_private)]
#![feature(assert_matches)]
#[macro_use]
extern crate rustc_smir;
extern crate rustc_driver;
extern crate rustc_interface;
extern crate stable_mir;
use rustc_smir::rustc_internal;
use stable_mir::ty::{Ty, ForeignItemKind};
use stable_mir::*;
use std::io::Write;
use std::ops::ControlFlow;
const CRATE_NAME: &str = "crate_def_ty";
/// Test if we can retrieve type information from different definitions.
fn test_def_tys() -> ControlFlow<()> {
let items = stable_mir::all_local_items();
for item in &items {
// Type from crate items.
let ty = item.ty();
match item.name().as_str() {
"STATIC_STR" => assert!(ty.kind().is_ref()),
"CONST_U32" => assert!(ty.kind().is_integral()),
"main" => { check_fn_def(ty) }
_ => unreachable!("Unexpected item: `{item:?}`")
}
}
let foreign_items = stable_mir::local_crate().foreign_modules();
for item in foreign_items[0].module().items() {
// Type from foreign items.
let ty = item.ty();
let item_kind = item.kind();
let name = item.name();
match item_kind {
ForeignItemKind::Fn(fn_def) => {
assert_eq!(&name, "extern_fn");
assert_eq!(ty, fn_def.ty());
check_fn_def(ty)
}
ForeignItemKind::Static(def) => {
assert_eq!(&name, "EXT_STATIC");
assert_eq!(ty, def.ty());
assert!(ty.kind().is_integral())
}
_ => unreachable!("Unexpected kind: {item_kind:?}")
};
}
ControlFlow::Continue(())
}
fn check_fn_def(ty: Ty) {
let kind = ty.kind();
let (def, args) = kind.fn_def().expect(&format!("Expected function type, but found: {ty}"));
assert!(def.ty().kind().is_fn());
assert_eq!(def.ty_with_args(args), ty);
}
/// This test will generate and analyze a dummy crate using the stable mir.
/// For that, it will first write the dummy crate into a file.
/// Then it will create a `StableMir` using custom arguments and then
/// it will run the compiler.
fn main() {
let path = "defs_ty_input.rs";
generate_input(&path).unwrap();
let args = vec![
"rustc".to_string(),
"-Cpanic=abort".to_string(),
"--crate-name".to_string(),
CRATE_NAME.to_string(),
path.to_string(),
];
run!(args, test_def_tys).unwrap();
}
fn generate_input(path: &str) -> std::io::Result<()> {
let mut file = std::fs::File::create(path)?;
write!(
file,
r#"
// We would like to check intrinsic definition.
#![feature(core_intrinsics)]
static STATIC_STR: &str = "foo";
const CONST_U32: u32 = 0u32;
fn main() {{
let _c = core::char::from_u32(99);
let _v = Vec::<u8>::new();
let _i = std::intrinsics::size_of::<u8>();
}}
extern "C" {{
fn extern_fn(x: i32) -> i32;
static EXT_STATIC: i32;
}}
"#
)?;
Ok(())
}