From 40185dba540dcbbc9e20e29b15fd69a25d52c256 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Fri, 3 Mar 2023 16:56:07 -0800 Subject: [PATCH 1/3] Delete old re-exports from rustc_smir This approach didn't seem to work well. --- compiler/rustc_smir/src/lib.rs | 4 ---- compiler/rustc_smir/src/mir.rs | 10 --------- compiler/rustc_smir/src/very_unstable.rs | 27 ------------------------ 3 files changed, 41 deletions(-) delete mode 100644 compiler/rustc_smir/src/mir.rs delete mode 100644 compiler/rustc_smir/src/very_unstable.rs diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 3e93c6bba977f..280b704f23326 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -13,7 +13,3 @@ #![cfg_attr(not(feature = "default"), feature(rustc_private))] #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] - -pub mod mir; - -pub mod very_unstable; diff --git a/compiler/rustc_smir/src/mir.rs b/compiler/rustc_smir/src/mir.rs deleted file mode 100644 index 887e657293066..0000000000000 --- a/compiler/rustc_smir/src/mir.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub use crate::very_unstable::hir::ImplicitSelfKind; -pub use crate::very_unstable::middle::mir::{ - visit::MutVisitor, AggregateKind, AssertKind, BasicBlock, BasicBlockData, BinOp, BindingForm, - BlockTailInfo, Body, BorrowKind, CastKind, ClearCrossCrate, Constant, ConstantKind, - CopyNonOverlapping, Coverage, FakeReadCause, Field, GeneratorInfo, InlineAsmOperand, Local, - LocalDecl, LocalInfo, LocalKind, Location, MirPhase, MirSource, NullOp, Operand, Place, - PlaceRef, ProjectionElem, ProjectionKind, Promoted, RetagKind, Rvalue, Safety, SourceInfo, - SourceScope, SourceScopeData, SourceScopeLocalData, Statement, StatementKind, UnOp, - UserTypeProjection, UserTypeProjections, VarBindingForm, VarDebugInfo, VarDebugInfoContents, -}; diff --git a/compiler/rustc_smir/src/very_unstable.rs b/compiler/rustc_smir/src/very_unstable.rs deleted file mode 100644 index 12ba133dbb169..0000000000000 --- a/compiler/rustc_smir/src/very_unstable.rs +++ /dev/null @@ -1,27 +0,0 @@ -//! This module reexports various crates and modules from unstable rustc APIs. -//! Add anything you need here and it will get slowly transferred to a stable API. -//! Only use rustc_smir in your dependencies and use the reexports here instead of -//! directly referring to the unstable crates. - -macro_rules! crates { - ($($rustc_name:ident -> $name:ident,)*) => { - $( - #[cfg(not(feature = "default"))] - pub extern crate $rustc_name as $name; - #[cfg(feature = "default")] - pub use $rustc_name as $name; - )* - } -} - -crates! { - rustc_borrowck -> borrowck, - rustc_driver -> driver, - rustc_hir -> hir, - rustc_interface -> interface, - rustc_middle -> middle, - rustc_mir_dataflow -> dataflow, - rustc_mir_transform -> transform, - rustc_serialize -> serialize, - rustc_trait_selection -> trait_selection, -} From b66db7e4e04ba039967b659473595a13409e0b18 Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Fri, 3 Mar 2023 17:08:49 -0800 Subject: [PATCH 2/3] Create new rustc_smir struct to map future crates + Add some information to the README.md --- Cargo.lock | 10 +- compiler/rustc_smir/Cargo.toml | 19 +--- compiler/rustc_smir/README.md | 37 ++++++ compiler/rustc_smir/rust-toolchain.toml | 2 +- compiler/rustc_smir/src/lib.rs | 8 +- compiler/rustc_smir/src/rustc_internal/mod.rs | 12 ++ compiler/rustc_smir/src/rustc_smir/mod.rs | 52 +++++++++ compiler/rustc_smir/src/stable_mir/mod.rs | 52 +++++++++ tests/ui-fulldeps/stable-mir/crate-info.rs | 106 ++++++++++++++++++ 9 files changed, 271 insertions(+), 27 deletions(-) create mode 100644 compiler/rustc_smir/src/rustc_internal/mod.rs create mode 100644 compiler/rustc_smir/src/rustc_smir/mod.rs create mode 100644 compiler/rustc_smir/src/stable_mir/mod.rs create mode 100644 tests/ui-fulldeps/stable-mir/crate-info.rs diff --git a/Cargo.lock b/Cargo.lock index 5530541cdd0f1..24e39e9d3f8a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4654,15 +4654,9 @@ dependencies = [ name = "rustc_smir" version = "0.0.0" dependencies = [ - "rustc_borrowck", - "rustc_driver", - "rustc_hir", - "rustc_interface", "rustc_middle", - "rustc_mir_dataflow", - "rustc_mir_transform", - "rustc_serialize", - "rustc_trait_selection", + "rustc_span", + "tracing", ] [[package]] diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 5e0d1f369a6a2..fb97ee5bebe6e 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -4,25 +4,12 @@ version = "0.0.0" edition = "2021" [dependencies] -rustc_borrowck = { path = "../rustc_borrowck", optional = true } -rustc_driver = { path = "../rustc_driver", optional = true } -rustc_hir = { path = "../rustc_hir", optional = true } -rustc_interface = { path = "../rustc_interface", optional = true } rustc_middle = { path = "../rustc_middle", optional = true } -rustc_mir_dataflow = { path = "../rustc_mir_dataflow", optional = true } -rustc_mir_transform = { path = "../rustc_mir_transform", optional = true } -rustc_serialize = { path = "../rustc_serialize", optional = true } -rustc_trait_selection = { path = "../rustc_trait_selection", optional = true } +rustc_span = { path = "../rustc_span", optional = true } +tracing = "0.1" [features] default = [ - "rustc_borrowck", - "rustc_driver", - "rustc_hir", - "rustc_interface", "rustc_middle", - "rustc_mir_dataflow", - "rustc_mir_transform", - "rustc_serialize", - "rustc_trait_selection", + "rustc_span", ] diff --git a/compiler/rustc_smir/README.md b/compiler/rustc_smir/README.md index ae49098dd0ce6..31dee955f491f 100644 --- a/compiler/rustc_smir/README.md +++ b/compiler/rustc_smir/README.md @@ -73,3 +73,40 @@ git subtree pull --prefix=compiler/rustc_smir https://github.com/rust-lang/proje Note: only ever sync to rustc from the project-stable-mir's `smir` branch. Do not sync with your own forks. Then open a PR against rustc just like a regular PR. + +## Stable MIR Design + +The stable-mir will follow a similar approach to proc-macro2. It’s +implementation will eventually be broken down into two main crates: + +- `stable_mir`: Public crate, to be published on crates.io, which will contain +the stable data structure as well as proxy APIs to make calls to the +compiler. +- `rustc_smir`: The compiler crate that will translate from internal MIR to +SMIR. This crate will also implement APIs that will be invoked by +stable-mir to query the compiler for more information. + +This will help tools to communicate with the rust compiler via stable APIs. Tools will depend on +`stable_mir` crate, which will invoke the compiler using APIs defined in `rustc_smir`. I.e.: + +``` + ┌──────────────────────────────────┐ ┌──────────────────────────────────┐ + │ External Tool ┌──────────┐ │ │ ┌──────────┐ Rust Compiler │ + │ │ │ │ │ │ │ │ + │ │stable_mir| │ │ │rustc_smir│ │ + │ │ │ ├──────────►| │ │ │ + │ │ │ │◄──────────┤ │ │ │ + │ │ │ │ │ │ │ │ + │ │ │ │ │ │ │ │ + │ └──────────┘ │ │ └──────────┘ │ + └──────────────────────────────────┘ └──────────────────────────────────┘ +``` + +More details can be found here: +https://hackmd.io/XhnYHKKuR6-LChhobvlT-g?view + +For now, the code for these two crates are in separate modules of this crate. +The modules have the same name for simplicity. We also have a third module, +`rustc_internal` which will expose APIs and definitions that allow users to +gather information from internal MIR constructs that haven't been exposed in +the `stable_mir` module. diff --git a/compiler/rustc_smir/rust-toolchain.toml b/compiler/rustc_smir/rust-toolchain.toml index 7b696fc1f5cec..157dfd620ee1b 100644 --- a/compiler/rustc_smir/rust-toolchain.toml +++ b/compiler/rustc_smir/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2022-06-01" +channel = "nightly-2023-02-28" components = [ "rustfmt", "rustc-dev" ] diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 280b704f23326..54d474db038e9 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -11,5 +11,9 @@ test(attr(allow(unused_variables), deny(warnings))) )] #![cfg_attr(not(feature = "default"), feature(rustc_private))] -#![deny(rustc::untranslatable_diagnostic)] -#![deny(rustc::diagnostic_outside_of_impl)] + +pub mod rustc_internal; +pub mod stable_mir; + +// Make this module private for now since external users should not call these directly. +mod rustc_smir; diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs new file mode 100644 index 0000000000000..044d6a2419f69 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -0,0 +1,12 @@ +//! Module that implements the bridge between Stable MIR and internal compiler MIR. +//! +//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs +//! until stable MIR is complete. + +use crate::stable_mir::CrateItem; + +pub type DefId = rustc_span::def_id::DefId; + +pub fn item_def_id(item: &CrateItem) -> DefId { + item.0 +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs new file mode 100644 index 0000000000000..768b01f526f73 --- /dev/null +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -0,0 +1,52 @@ +//! Module that implements what will become the rustc side of Stable MIR. +//! +//! This module is responsible for building Stable MIR components from internal components. +//! +//! This module is not intended to be invoked directly by users. It will eventually +//! become the public API of rustc that will be invoked by the `stable_mir` crate. +//! +//! For now, we are developing everything inside `rustc`, thus, we keep this module private. + +use crate::stable_mir::{self}; +use rustc_middle::ty::{tls::with, TyCtxt}; +use rustc_span::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use tracing::debug; + +/// Get information about the local crate. +pub fn local_crate() -> stable_mir::Crate { + with(|tcx| smir_crate(tcx, LOCAL_CRATE)) +} + +/// Find a crate with the given name. +pub fn find_crate(name: &str) -> Option { + with(|tcx| { + [LOCAL_CRATE].iter().chain(tcx.crates(()).iter()).find_map(|crate_num| { + let crate_name = tcx.crate_name(*crate_num).to_string(); + (name == crate_name).then(|| smir_crate(tcx, *crate_num)) + }) + }) +} + +/// Build a stable mir crate from a given crate number. +fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { + let crate_name = tcx.crate_name(crate_num).to_string(); + let is_local = crate_num == LOCAL_CRATE; + let mod_id = DefId { index: CRATE_DEF_INDEX, krate: crate_num }; + let items = if is_local { + tcx.hir_module_items(mod_id.expect_local()) + .items() + .map(|item| { + let def_id = item.owner_id.def_id.to_def_id(); + stable_mir::CrateItem(def_id) + }) + .collect() + } else { + tcx.module_children(mod_id) + .iter() + .filter_map(|item| item.res.opt_def_id()) + .map(stable_mir::CrateItem) + .collect::>() + }; + debug!(?crate_name, ?crate_num, "smir_crate"); + stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local, root_items: items } +} diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs new file mode 100644 index 0000000000000..f61ea461dfa85 --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -0,0 +1,52 @@ +//! Module that implements the public interface to the Stable MIR. +//! +//! This module shall contain all type definitions and APIs that we expect 3P tools to invoke to +//! interact with the compiler. +//! +//! The goal is to eventually move this module to its own crate which shall be published on +//! [crates.io](https://crates.io). +//! +//! ## Note: +//! +//! There shouldn't be any direct references to internal compiler constructs in this module. +//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`. + +use crate::rustc_internal; + +/// Use String for now but we should replace it. +pub type Symbol = String; + +/// The number that identifies a crate. +pub type CrateNum = usize; + +/// A unique identification number for each item accessible for the current compilation unit. +pub type DefId = usize; + +/// A list of crate items. +pub type CrateItems = Vec; + +/// Holds information about a crate. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct Crate { + pub(crate) id: CrateNum, + pub name: Symbol, + pub is_local: bool, + /// The items defined in the root of this crate. + pub root_items: CrateItems, +} + +/// Holds information about an item in the crate. +/// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to +/// use this item. +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct CrateItem(pub(crate) rustc_internal::DefId); + +/// Access to the local crate. +pub fn local_crate() -> Crate { + crate::rustc_smir::local_crate() +} + +/// Try to find a crate with the given name. +pub fn find_crate(name: &str) -> Option { + crate::rustc_smir::find_crate(name) +} 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 0000000000000..62cfb809fcbe9 --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -0,0 +1,106 @@ +// run-pass +// Test that users are able to use stable mir APIs to retrieve information of the current crate + +// ignore-stage-1 +// ignore-cross-compile +// ignore-remote + +#![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); + + // Find items in the local crate. + assert!(has_root_item(tcx, &local, (DefKind::Fn, "foo_bar"))); + assert!(has_root_item(tcx, &local, (DefKind::Mod, "foo"))); + assert!(!has_root_item(tcx, &local, (DefKind::Fn, "foo::bar"))); + + // Check that we can find items in the `std` crate. + let std_crate = stable_mir::find_crate("std").unwrap(); + assert!(has_root_item(tcx, &std_crate, (DefKind::Mod, "std::any"))); + assert!(!has_root_item(tcx, &std_crate, (DefKind::Fn, "std::any::type_name"))); +} + +// Use internal API to find a function in a crate. +fn has_root_item(tcx: TyCtxt, krate: &stable_mir::Crate, item: (DefKind, &str)) -> bool { + krate.root_items.iter().any(|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 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(()) +} From 5eaeb71b9f0c27a3bfab666b3f5288c83c63eafe Mon Sep 17 00:00:00 2001 From: "Celina G. Val" Date: Tue, 7 Mar 2023 12:47:25 -0800 Subject: [PATCH 3/3] Change item collection to be on demand --- compiler/rustc_smir/src/rustc_internal/mod.rs | 11 ++++--- compiler/rustc_smir/src/rustc_smir/mod.rs | 32 ++++++++----------- compiler/rustc_smir/src/stable_mir/mod.rs | 12 +++++-- tests/ui-fulldeps/stable-mir/crate-info.rs | 16 ++++------ 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 044d6a2419f69..3eaff9c051f1c 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -3,10 +3,13 @@ //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs //! until stable MIR is complete. -use crate::stable_mir::CrateItem; +use crate::stable_mir; +pub use rustc_span::def_id::{CrateNum, DefId}; -pub type DefId = rustc_span::def_id::DefId; - -pub fn item_def_id(item: &CrateItem) -> DefId { +pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId { item.0 } + +pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { + item.id.into() +} diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 768b01f526f73..d956f0ac80213 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -9,7 +9,7 @@ use crate::stable_mir::{self}; use rustc_middle::ty::{tls::with, TyCtxt}; -use rustc_span::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE}; +use rustc_span::def_id::{CrateNum, LOCAL_CRATE}; use tracing::debug; /// Get information about the local crate. @@ -17,6 +17,11 @@ pub fn local_crate() -> stable_mir::Crate { with(|tcx| smir_crate(tcx, LOCAL_CRATE)) } +/// Retrieve a list of all external crates. +pub fn external_crates() -> Vec { + with(|tcx| tcx.crates(()).iter().map(|crate_num| smir_crate(tcx, *crate_num)).collect()) +} + /// Find a crate with the given name. pub fn find_crate(name: &str) -> Option { with(|tcx| { @@ -27,26 +32,17 @@ pub fn find_crate(name: &str) -> Option { }) } +/// Retrieve all items of the local crate that have a MIR associated with them. +pub fn all_local_items() -> stable_mir::CrateItems { + with(|tcx| { + tcx.mir_keys(()).iter().map(|item| stable_mir::CrateItem(item.to_def_id())).collect() + }) +} + /// Build a stable mir crate from a given crate number. fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate { let crate_name = tcx.crate_name(crate_num).to_string(); let is_local = crate_num == LOCAL_CRATE; - let mod_id = DefId { index: CRATE_DEF_INDEX, krate: crate_num }; - let items = if is_local { - tcx.hir_module_items(mod_id.expect_local()) - .items() - .map(|item| { - let def_id = item.owner_id.def_id.to_def_id(); - stable_mir::CrateItem(def_id) - }) - .collect() - } else { - tcx.module_children(mod_id) - .iter() - .filter_map(|item| item.res.opt_def_id()) - .map(stable_mir::CrateItem) - .collect::>() - }; debug!(?crate_name, ?crate_num, "smir_crate"); - stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local, root_items: items } + stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local } } diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/rustc_smir/src/stable_mir/mod.rs index f61ea461dfa85..cbf52e691fb47 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/rustc_smir/src/stable_mir/mod.rs @@ -31,8 +31,6 @@ pub struct Crate { pub(crate) id: CrateNum, pub name: Symbol, pub is_local: bool, - /// The items defined in the root of this crate. - pub root_items: CrateItems, } /// Holds information about an item in the crate. @@ -50,3 +48,13 @@ pub fn local_crate() -> Crate { pub fn find_crate(name: &str) -> Option { crate::rustc_smir::find_crate(name) } + +/// Try to find a crate with the given name. +pub fn external_crates() -> Vec { + crate::rustc_smir::external_crates() +} + +/// Retrieve all items in the local crate that have a MIR associated with them. +pub fn all_local_items() -> CrateItems { + crate::rustc_smir::all_local_items() +} diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index 62cfb809fcbe9..4458ab0162e95 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -29,19 +29,17 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { assert_eq!(&local.name, CRATE_NAME); // Find items in the local crate. - assert!(has_root_item(tcx, &local, (DefKind::Fn, "foo_bar"))); - assert!(has_root_item(tcx, &local, (DefKind::Mod, "foo"))); - assert!(!has_root_item(tcx, &local, (DefKind::Fn, "foo::bar"))); + let items = stable_mir::all_local_items(); + assert!(has_item(tcx, &items, (DefKind::Fn, "foo_bar"))); + assert!(has_item(tcx, &items, (DefKind::Fn, "foo::bar"))); - // Check that we can find items in the `std` crate. - let std_crate = stable_mir::find_crate("std").unwrap(); - assert!(has_root_item(tcx, &std_crate, (DefKind::Mod, "std::any"))); - assert!(!has_root_item(tcx, &std_crate, (DefKind::Fn, "std::any::type_name"))); + // Find the `std` crate. + assert!(stable_mir::find_crate("std").is_some()); } // Use internal API to find a function in a crate. -fn has_root_item(tcx: TyCtxt, krate: &stable_mir::Crate, item: (DefKind, &str)) -> bool { - krate.root_items.iter().any(|crate_item| { +fn has_item(tcx: TyCtxt, items: &stable_mir::CrateItems, item: (DefKind, &str)) -> bool { + items.iter().any(|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 })