diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:20:39 +0000 |
commit | 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 (patch) | |
tree | 3bb8d61aee02bc7a15eab3f36e3b921afc2075d0 /tests/ui-fulldeps/stable-mir | |
parent | Releasing progress-linux version 1.69.0+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.tar.xz rustc-1376c5a617be5c25655d0d7cb63e3beaa5a6e026.zip |
Merging upstream version 1.70.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui-fulldeps/stable-mir')
-rw-r--r-- | tests/ui-fulldeps/stable-mir/crate-info.rs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs new file mode 100644 index 000000000..dfde8c97e --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -0,0 +1,129 @@ +// run-pass +// Test that users are able to use stable mir APIs to retrieve information of the current crate + +// ignore-stage1 +// ignore-cross-compile +// ignore-remote +// edition: 2021 + +#![feature(rustc_private)] + +extern crate rustc_driver; +extern crate rustc_hir; +extern crate rustc_interface; +extern crate rustc_middle; +extern crate rustc_smir; + +use rustc_driver::{Callbacks, Compilation, RunCompiler}; +use rustc_hir::def::DefKind; +use rustc_interface::{interface, Queries}; +use rustc_middle::ty::TyCtxt; +use rustc_smir::{rustc_internal, stable_mir}; +use std::io::Write; + +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<'_>) { + // Get the local crate using stable_mir API. + let local = stable_mir::local_crate(); + assert_eq!(&local.name, CRATE_NAME); + + assert_eq!(stable_mir::entry_fn(), None); + + // Find items in the local crate. + let items = stable_mir::all_local_items(); + assert!(get_item(tcx, &items, (DefKind::Fn, "foo_bar")).is_some()); + assert!(get_item(tcx, &items, (DefKind::Fn, "foo::bar")).is_some()); + + // Find the `std` crate. + assert!(stable_mir::find_crate("std").is_some()); + + let bar = get_item(tcx, &items, (DefKind::Fn, "bar")).unwrap(); + let body = bar.body(); + assert_eq!(body.blocks.len(), 1); + let block = &body.blocks[0]; + assert_eq!(block.statements.len(), 1); + match &block.statements[0] { + stable_mir::mir::Statement::Assign(..) => {} + other => panic!("{other:?}"), + } + match &block.terminator { + stable_mir::mir::Terminator::Return => {} + other => panic!("{other:?}"), + } +} + +// Use internal API to find a function in a crate. +fn get_item<'a>( + tcx: TyCtxt, + items: &'a stable_mir::CrateItems, + item: (DefKind, &str), +) -> Option<&'a stable_mir::CrateItem> { + items.iter().find(|crate_item| { + let def_id = rustc_internal::item_def_id(crate_item); + tcx.def_kind(def_id) == item.0 && tcx.def_path_str(def_id) == item.1 + }) +} + +/// 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. +/// It will invoke the compiler using a custom Callback implementation, which will +/// invoke Stable MIR APIs after the compiler has finished its analysis. +fn main() { + let path = "input.rs"; + generate_input(&path).unwrap(); + let args = vec![ + "rustc".to_string(), + "--crate-type=lib".to_string(), + "--crate-name".to_string(), + CRATE_NAME.to_string(), + path.to_string(), + ]; + rustc_driver::catch_fatal_errors(|| { + RunCompiler::new(&args, &mut SMirCalls {}).run().unwrap(); + }) + .unwrap(); +} + +struct SMirCalls {} + +impl Callbacks for SMirCalls { + /// Called after analysis. Return value instructs the compiler whether to + /// continue the compilation afterwards (defaults to `Compilation::Continue`) + fn after_analysis<'tcx>( + &mut self, + _compiler: &interface::Compiler, + queries: &'tcx Queries<'tcx>, + ) -> Compilation { + queries.global_ctxt().unwrap().enter(|tcx| { + test_stable_mir(tcx); + }); + // No need to keep going. + Compilation::Stop + } +} + +fn generate_input(path: &str) -> std::io::Result<()> { + let mut file = std::fs::File::create(path)?; + write!( + file, + r#" + mod foo {{ + pub fn bar(i: i32) -> i64 {{ + i as i64 + }} + }} + + pub fn bar(x: i32) -> i32 {{ + x + }} + + pub fn foo_bar(x: i32, y: i32) -> i64 {{ + let x_64 = foo::bar(x); + let y_64 = foo::bar(y); + x_64.wrapping_add(y_64) + }}"# + )?; + Ok(()) +} |