diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index cf6ac5285c2..e1ee40c0b60 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -15,7 +15,7 @@ use stable_mir::abi::Layout; use stable_mir::mir::mono::InstanceDef; use stable_mir::ty::{ConstId, Span}; -use stable_mir::ItemKind; +use stable_mir::{CtorKind, ItemKind}; use std::ops::RangeInclusive; use tracing::debug; @@ -88,7 +88,6 @@ pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { | DefKind::Field | DefKind::LifetimeParam | DefKind::Impl { .. } - | DefKind::Ctor(_, _) | DefKind::GlobalAsm => { unreachable!("Not a valid item kind: {kind:?}"); } @@ -97,6 +96,8 @@ pub(crate) fn new_item_kind(kind: DefKind) -> ItemKind { ItemKind::Const } DefKind::Static(_) => ItemKind::Static, + DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const), + DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn), } } diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs index 4941e54fe4b..9194f1e6bdb 100644 --- a/compiler/stable_mir/src/lib.rs +++ b/compiler/stable_mir/src/lib.rs @@ -91,6 +91,13 @@ pub enum ItemKind { Fn, Static, Const, + Ctor(CtorKind), +} + +#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] +pub enum CtorKind { + Const, + Fn, } pub type Filename = String; diff --git a/tests/ui-fulldeps/stable-mir/check_item_kind.rs b/tests/ui-fulldeps/stable-mir/check_item_kind.rs new file mode 100644 index 00000000000..72e0e09e6e3 --- /dev/null +++ b/tests/ui-fulldeps/stable-mir/check_item_kind.rs @@ -0,0 +1,84 @@ +// run-pass +//! Test that item kind works as expected. + +// 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 rustc_middle::ty::TyCtxt; +use rustc_smir::rustc_internal; +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_item_kind(_tcx: TyCtxt<'_>) -> ControlFlow<()> { + let items = stable_mir::all_local_items(); + assert_eq!(items.len(), 4); + // Constructor item. + for item in items { + let expected_kind = match item.name().as_str() { + "Dummy" => ItemKind::Ctor(CtorKind::Fn), + "dummy" => ItemKind::Fn, + "unit" => ItemKind::Fn, + "DUMMY_CONST" => ItemKind::Const, + name => unreachable!("Unexpected item {name}"), + }; + assert_eq!(item.kind(), expected_kind, "Mismatched type for {}", item.name()); + } + ControlFlow::Continue(()) +} + +/// 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 = "item_kind_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_item_kind(tcx)).unwrap(); +} + +fn generate_input(path: &str) -> std::io::Result<()> { + let mut file = std::fs::File::create(path)?; + write!( + file, + r#" + pub struct Dummy(u32); + pub const DUMMY_CONST: Dummy = Dummy(0); + pub struct DummyUnit; + + pub fn dummy() -> Dummy {{ + Dummy(5) + }} + + pub fn unit() -> DummyUnit {{ + DummyUnit + }} + "# + )?; + Ok(()) +}