diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
commit | ef24de24a82fe681581cc130f342363c47c0969a (patch) | |
tree | 0d494f7e1a38b95c92426f58fe6eaa877303a86c /tests/ui-fulldeps/stable-mir/check_instance.rs | |
parent | Releasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip |
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui-fulldeps/stable-mir/check_instance.rs')
-rw-r--r-- | tests/ui-fulldeps/stable-mir/check_instance.rs | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/tests/ui-fulldeps/stable-mir/check_instance.rs b/tests/ui-fulldeps/stable-mir/check_instance.rs new file mode 100644 index 000000000..a34087775 --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/check_instance.rs @@ -0,0 +1,122 @@ +// run-pass +//! Test that users are able to use stable mir APIs to retrieve monomorphized instances + +// 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)] +#![feature(control_flow_enum)] + +extern crate rustc_middle; +#[macro_use] +extern crate rustc_smir; +extern crate rustc_driver; +extern crate rustc_interface; +extern crate stable_mir; + +use mir::{mono::Instance, TerminatorKind::*}; +use rustc_middle::ty::TyCtxt; +use rustc_smir::rustc_internal; +use stable_mir::ty::{RigidTy, TyKind}; +use stable_mir::*; +use std::io::Write; +use std::ops::ControlFlow; + +const CRATE_NAME: &str = "input"; + +/// This function uses the Stable MIR APIs to get information about the test crate. +fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { + let items = stable_mir::all_local_items(); + + // Get all items and split generic vs monomorphic items. + let (generic, mono): (Vec<_>, Vec<_>) = + items.into_iter().partition(|item| item.requires_monomorphization()); + assert_eq!(mono.len(), 3, "Expected 2 mono functions and one constant"); + assert_eq!(generic.len(), 2, "Expected 2 generic functions"); + + // For all monomorphic items, get the correspondent instances. + let instances = mono + .iter() + .filter_map(|item| mir::mono::Instance::try_from(*item).ok()) + .collect::<Vec<mir::mono::Instance>>(); + assert_eq!(instances.len(), mono.len()); + + // For all generic items, try_from should fail. + assert!(generic.iter().all(|item| mir::mono::Instance::try_from(*item).is_err())); + + for instance in instances { + test_body(instance.body()) + } + ControlFlow::Continue(()) +} + +/// Inspect the instance body +fn test_body(body: mir::Body) { + for term in body.blocks.iter().map(|bb| &bb.terminator) { + match &term.kind { + Call { func, .. } => { + let TyKind::RigidTy(ty) = func.ty(body.locals()).kind() else { unreachable!() }; + let RigidTy::FnDef(def, args) = ty else { unreachable!() }; + let result = Instance::resolve(def, &args); + assert!(result.is_ok()); + } + Goto { .. } | Assert { .. } | SwitchInt { .. } | Return | Drop { .. } => { + /* Do nothing */ + } + _ => { + unreachable!("Unexpected terminator {term:?}") + } + } + } +} + +/// 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 = "instance_input.rs"; + generate_input(&path).unwrap(); + let args = vec![ + "rustc".to_string(), + "-Cpanic=abort".to_string(), + "--crate-type=lib".to_string(), + "--crate-name".to_string(), + CRATE_NAME.to_string(), + path.to_string(), + ]; + run!(args, tcx, test_stable_mir(tcx)).unwrap(); +} + +fn generate_input(path: &str) -> std::io::Result<()> { + let mut file = std::fs::File::create(path)?; + write!( + file, + r#" + pub fn ty_param<T>(t: &T) -> T where T: Clone {{ + t.clone() + }} + + pub fn const_param<const LEN: usize>(a: [bool; LEN]) -> bool {{ + LEN > 0 && a[0] + }} + + pub fn monomorphic() {{ + let v = vec![10]; + let dup = ty_param(&v); + assert_eq!(v, dup); + }} + + pub mod foo {{ + pub fn bar_mono(i: i32) -> i64 {{ + i as i64 + }} + }} + "# + )?; + Ok(()) +} |