about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs12
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs37
-rw-r--r--compiler/stable_mir/src/crate_def.rs69
-rw-r--r--compiler/stable_mir/src/lib.rs27
-rw-r--r--compiler/stable_mir/src/mir/mono.rs32
-rw-r--r--compiler/stable_mir/src/mir/pretty.rs1
-rw-r--r--compiler/stable_mir/src/ty.rs73
-rw-r--r--tests/ui-fulldeps/stable-mir/check_allocation.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/check_defs.rs106
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs1
-rw-r--r--tests/ui-fulldeps/stable-mir/projections.rs1
11 files changed, 307 insertions, 53 deletions
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index fe226ef60ed..202ca1b156a 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -11,8 +11,8 @@ use stable_mir::mir::alloc::AllocId;
 use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
 use stable_mir::ty::{
     AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const,
-    ExistentialTraitRef, FloatTy, GenericArgKind, GenericArgs, IntTy, Region, RigidTy, TraitRef,
-    Ty, UintTy,
+    ExistentialTraitRef, FloatTy, GenericArgKind, GenericArgs, IntTy, Region, RigidTy, Span,
+    TraitRef, Ty, UintTy,
 };
 use stable_mir::{CrateItem, DefId};
 
@@ -279,6 +279,14 @@ impl<'tcx> RustcInternal<'tcx> for AdtDef {
     }
 }
 
+impl<'tcx> RustcInternal<'tcx> for Span {
+    type T = rustc_span::Span;
+
+    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        tables[*self]
+    }
+}
+
 impl<'tcx, T> RustcInternal<'tcx> for &T
 where
     T: RustcInternal<'tcx>,
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index 8b469882cd1..9921a89eb23 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -14,6 +14,7 @@ use rustc_hir::def::DefKind;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{alloc_range, AllocId};
 use rustc_middle::mir::mono::MonoItem;
+use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
 use rustc_middle::ty::{self, Instance, ParamEnv, ScalarInt, Ty, TyCtxt, Variance};
 use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_target::abi::FieldIdx;
@@ -28,7 +29,7 @@ use stable_mir::ty::{
     EarlyParamRegion, FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability,
     RigidTy, Span, TyKind, UintTy,
 };
-use stable_mir::{self, opaque, Context, CrateItem, Error, Filename, ItemKind};
+use stable_mir::{self, opaque, Context, Crate, CrateItem, Error, Filename, ItemKind, Symbol};
 use std::cell::RefCell;
 use tracing::debug;
 
@@ -61,9 +62,18 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         crates
     }
 
-    fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String {
+    fn def_name(&self, def_id: stable_mir::DefId, trimmed: bool) -> Symbol {
         let tables = self.0.borrow();
-        tables.tcx.def_path_str(tables[def_id])
+        if trimmed {
+            with_forced_trimmed_paths!(tables.tcx.def_path_str(tables[def_id]))
+        } else {
+            with_no_trimmed_paths!(tables.tcx.def_path_str(tables[def_id]))
+        }
+    }
+
+    fn krate(&self, def_id: stable_mir::DefId) -> Crate {
+        let tables = self.0.borrow();
+        smir_crate(tables.tcx, tables[def_id].krate)
     }
 
     fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
@@ -240,12 +250,29 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
         tables.create_def_id(def_id)
     }
 
-    fn instance_mangled_name(&self, def: InstanceDef) -> String {
+    fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol {
         let tables = self.0.borrow_mut();
-        let instance = tables.instances[def];
+        let instance = tables.instances[instance];
         tables.tcx.symbol_name(instance).name.to_string()
     }
 
+    /// Retrieve the instance name for diagnostic messages.
+    ///
+    /// This will return the specialized name, e.g., `Vec<char>::new`.
+    fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol {
+        let tables = self.0.borrow_mut();
+        let instance = tables.instances[def];
+        if trimmed {
+            with_forced_trimmed_paths!(
+                tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
+            )
+        } else {
+            with_no_trimmed_paths!(
+                tables.tcx.def_path_str_with_args(instance.def_id(), instance.args)
+            )
+        }
+    }
+
     fn mono_instance(&self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
         let mut tables = self.0.borrow_mut();
         let def_id = tables[item.0];
diff --git a/compiler/stable_mir/src/crate_def.rs b/compiler/stable_mir/src/crate_def.rs
new file mode 100644
index 00000000000..70ca9e6825e
--- /dev/null
+++ b/compiler/stable_mir/src/crate_def.rs
@@ -0,0 +1,69 @@
+//! Module that define a common trait for things that represent a crate definition,
+//! such as, a function, a trait, an enum, and any other definitions.
+
+use crate::ty::Span;
+use crate::{with, Crate, Symbol};
+
+/// A unique identification number for each item accessible for the current compilation unit.
+#[derive(Clone, Copy, PartialEq, Eq, Hash)]
+pub struct DefId(pub(crate) usize);
+
+/// A trait for retrieving information about a particular definition.
+///
+/// Implementors must provide the implementation of `def_id` which will be used to retrieve
+/// information about a crate's definition.
+pub trait CrateDef {
+    /// Retrieve the unique identifier for the current definition.
+    fn def_id(&self) -> DefId;
+
+    /// Return the fully qualified name of the current definition.
+    fn name(&self) -> Symbol {
+        let def_id = self.def_id();
+        with(|cx| cx.def_name(def_id, false))
+    }
+
+    /// Return a trimmed name of this definition.
+    ///
+    /// This can be used to print more user friendly diagnostic messages.
+    ///
+    /// If a symbol name can only be imported from one place for a type, and as
+    /// long as it was not glob-imported anywhere in the current crate, we trim its
+    /// path and print only the name.
+    ///
+    /// For example, this function may shorten `std::vec::Vec` to just `Vec`,
+    /// as long as there is no other `Vec` importable anywhere.
+    fn trimmed_name(&self) -> Symbol {
+        let def_id = self.def_id();
+        with(|cx| cx.def_name(def_id, true))
+    }
+
+    /// Return information about the crate where this definition is declared.
+    ///
+    /// This will return the crate number and its name.
+    fn krate(&self) -> Crate {
+        let def_id = self.def_id();
+        with(|cx| cx.krate(def_id))
+    }
+
+    /// Return the span of this definition.
+    fn span(&self) -> Span {
+        let def_id = self.def_id();
+        with(|cx| cx.span_of_an_item(def_id))
+    }
+}
+
+macro_rules! crate_def {
+    ( $(#[$attr:meta])*
+      $vis:vis $name:ident $(;)?
+    ) => {
+        $(#[$attr])*
+        #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
+        $vis struct $name(pub DefId);
+
+        impl CrateDef for $name {
+            fn def_id(&self) -> DefId {
+                self.0
+            }
+        }
+    };
+}
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index 6c1b723a8da..1b1faea4953 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -32,11 +32,15 @@ use self::ty::{
 extern crate scoped_tls;
 
 #[macro_use]
+pub mod crate_def;
+#[macro_use]
 pub mod error;
 pub mod mir;
 pub mod ty;
 pub mod visitor;
 
+pub use crate::crate_def::CrateDef;
+pub use crate::crate_def::DefId;
 use crate::mir::alloc::{AllocId, GlobalAlloc};
 use crate::mir::pretty::function_name;
 use crate::mir::Mutability;
@@ -51,15 +55,11 @@ 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.
-#[derive(Clone, Copy, PartialEq, Eq, Hash)]
-pub struct DefId(usize);
-
 impl Debug for DefId {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("DefId")
             .field("id", &self.0)
-            .field("name", &with(|cx| cx.name_of_def_id(*self)))
+            .field("name", &with(|cx| cx.def_name(*self, false)))
             .finish()
     }
 }
@@ -100,9 +100,10 @@ pub enum ItemKind {
 
 pub type Filename = String;
 
-/// Holds information about an item in the crate.
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub struct CrateItem(pub DefId);
+crate_def! {
+    /// Holds information about an item in a crate.
+    pub CrateItem;
+}
 
 impl CrateItem {
     pub fn body(&self) -> mir::Body {
@@ -113,10 +114,6 @@ impl CrateItem {
         with(|cx| cx.span_of_an_item(self.0))
     }
 
-    pub fn name(&self) -> String {
-        with(|cx| cx.name_of_def_id(self.0))
-    }
-
     pub fn kind(&self) -> ItemKind {
         with(|cx| cx.item_kind(*self))
     }
@@ -205,7 +202,7 @@ pub trait Context {
     fn find_crates(&self, name: &str) -> Vec<Crate>;
 
     /// Returns the name of given `DefId`
-    fn name_of_def_id(&self, def_id: DefId) -> String;
+    fn def_name(&self, def_id: DefId, trimmed: bool) -> Symbol;
 
     /// Returns printable, human readable form of `Span`
     fn span_to_string(&self, span: Span) -> String;
@@ -260,7 +257,7 @@ pub trait Context {
     fn instance_def_id(&self, instance: InstanceDef) -> DefId;
 
     /// Get the instance mangled name.
-    fn instance_mangled_name(&self, instance: InstanceDef) -> String;
+    fn instance_mangled_name(&self, instance: InstanceDef) -> Symbol;
 
     /// Convert a non-generic crate item into an instance.
     /// This function will panic if the item is generic.
@@ -294,6 +291,8 @@ pub trait Context {
 
     /// Retrieve the id for the virtual table.
     fn vtable_allocation(&self, global_alloc: &GlobalAlloc) -> Option<AllocId>;
+    fn krate(&self, def_id: DefId) -> Crate;
+    fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol;
 }
 
 // A thread local variable that stores a pointer to the tables mapping between TyCtxt
diff --git a/compiler/stable_mir/src/mir/mono.rs b/compiler/stable_mir/src/mir/mono.rs
index 9cec963cf84..8e884f17573 100644
--- a/compiler/stable_mir/src/mir/mono.rs
+++ b/compiler/stable_mir/src/mir/mono.rs
@@ -1,6 +1,7 @@
+use crate::crate_def::CrateDef;
 use crate::mir::Body;
 use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
-use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque};
+use crate::{with, CrateItem, DefId, Error, ItemKind, Opaque, Symbol};
 use std::fmt::{Debug, Formatter};
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -47,10 +48,29 @@ impl Instance {
         with(|context| context.instance_ty(self.def))
     }
 
-    pub fn mangled_name(&self) -> String {
+    /// Retrieve the instance's mangled name used for calling the given instance.
+    ///
+    /// This will also look up the correct name of instances from upstream crates.
+    pub fn mangled_name(&self) -> Symbol {
         with(|context| context.instance_mangled_name(self.def))
     }
 
+    /// Retrieve the instance name for diagnostic messages.
+    ///
+    /// This will return the specialized name, e.g., `std::vec::Vec<u8>::new`.
+    pub fn name(&self) -> Symbol {
+        with(|context| context.instance_name(self.def, false))
+    }
+
+    /// Return a trimmed name of the given instance including its args.
+    ///
+    /// If a symbol name can only be imported from one place for a type, and as
+    /// long as it was not glob-imported anywhere in the current crate, we trim its
+    /// path and print only the name.
+    pub fn trimmed_name(&self) -> Symbol {
+        with(|context| context.instance_name(self.def, true))
+    }
+
     /// Resolve an instance starting from a function definition and generic arguments.
     pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> {
         with(|context| {
@@ -104,6 +124,8 @@ impl TryFrom<CrateItem> for Instance {
 
     fn try_from(item: CrateItem) -> Result<Self, Self::Error> {
         with(|context| {
+            // FIXME(celinval):
+            // - Return `Err` if instance does not have a body.
             if !context.requires_monomorphization(item.0) {
                 Ok(context.mono_instance(item))
             } else {
@@ -148,8 +170,10 @@ impl From<StaticDef> for CrateItem {
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub struct InstanceDef(usize);
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
-pub struct StaticDef(pub DefId);
+crate_def! {
+    /// Holds information about a static variable definition.
+    pub StaticDef;
+}
 
 impl TryFrom<CrateItem> for StaticDef {
     type Error = crate::Error;
diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs
index c7422d66c0e..c16d7ddf335 100644
--- a/compiler/stable_mir/src/mir/pretty.rs
+++ b/compiler/stable_mir/src/mir/pretty.rs
@@ -1,3 +1,4 @@
+use crate::crate_def::CrateDef;
 use crate::mir::{Operand, Rvalue, StatementKind};
 use crate::ty::{DynKind, FloatTy, IntTy, RigidTy, TyKind, UintTy};
 use crate::{with, Body, CrateItem, Mutability};
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 19b7abaf2a8..80558657deb 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -3,6 +3,7 @@ use super::{
     mir::{Body, Mutability},
     with, DefId, Error, Symbol,
 };
+use crate::crate_def::CrateDef;
 use crate::mir::alloc::AllocId;
 use crate::{Filename, Opaque};
 use std::fmt::{self, Debug, Display, Formatter};
@@ -295,11 +296,15 @@ pub enum Movability {
     Movable,
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ForeignDef(pub DefId);
+crate_def! {
+    /// Hold information about a ForeignItem in a crate.
+    pub ForeignDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct FnDef(pub DefId);
+crate_def! {
+    /// Hold information about a function definition in a crate.
+    pub FnDef;
+}
 
 impl FnDef {
     pub fn body(&self) -> Body {
@@ -307,20 +312,25 @@ impl FnDef {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ClosureDef(pub DefId);
+crate_def! {
+    pub ClosureDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct CoroutineDef(pub DefId);
+crate_def! {
+    pub CoroutineDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ParamDef(pub DefId);
+crate_def! {
+    pub ParamDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct BrNamedDef(pub DefId);
+crate_def! {
+    pub BrNamedDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AdtDef(pub DefId);
+crate_def! {
+    pub AdtDef;
+}
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
 pub enum AdtKind {
@@ -363,26 +373,33 @@ impl AdtKind {
     }
 }
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AliasDef(pub DefId);
+crate_def! {
+    pub AliasDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct TraitDef(pub DefId);
+crate_def! {
+    pub TraitDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct GenericDef(pub DefId);
+crate_def! {
+    pub GenericDef;
+}
 
-#[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ConstDef(pub DefId);
+crate_def! {
+    pub ConstDef;
+}
 
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct ImplDef(pub DefId);
+crate_def! {
+    pub ImplDef;
+}
 
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct RegionDef(pub DefId);
+crate_def! {
+    pub RegionDef;
+}
 
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct CoroutineWitnessDef(pub DefId);
+crate_def! {
+    pub CoroutineWitnessDef;
+}
 
 /// A list of generic arguments.
 #[derive(Clone, Debug, Eq, PartialEq)]
diff --git a/tests/ui-fulldeps/stable-mir/check_allocation.rs b/tests/ui-fulldeps/stable-mir/check_allocation.rs
index e5fb7311c0b..170b1fd73b1 100644
--- a/tests/ui-fulldeps/stable-mir/check_allocation.rs
+++ b/tests/ui-fulldeps/stable-mir/check_allocation.rs
@@ -24,6 +24,7 @@ extern crate stable_mir;
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
 use stable_mir::{CrateItem, CrateItems, ItemKind};
+use stable_mir::crate_def::CrateDef;
 use stable_mir::mir::alloc::GlobalAlloc;
 use stable_mir::mir::mono::StaticDef;
 use std::ascii::Char;
diff --git a/tests/ui-fulldeps/stable-mir/check_defs.rs b/tests/ui-fulldeps/stable-mir/check_defs.rs
new file mode 100644
index 00000000000..bbb49596288
--- /dev/null
+++ b/tests/ui-fulldeps/stable-mir/check_defs.rs
@@ -0,0 +1,106 @@
+// run-pass
+//! Test that users are able to use stable mir APIs to retrieve information about crate definitions.
+
+// 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 entry = stable_mir::entry_fn().unwrap();
+    let main_fn = Instance::try_from(entry).unwrap();
+    assert_eq!(main_fn.name(), "main");
+    assert_eq!(main_fn.trimmed_name(), "main");
+
+    let instances = get_instances(main_fn.body().unwrap());
+    assert_eq!(instances.len(), 2);
+    test_fn(instances[0], "from_u32", "std::char::from_u32", "core");
+    test_fn(instances[1], "Vec::<u8>::new", "std::vec::Vec::<u8>::new", "alloc");
+    ControlFlow::Continue(())
+}
+
+fn test_fn(instance: Instance, expected_trimmed: &str, expected_qualified: &str, krate: &str) {
+    let trimmed = instance.trimmed_name();
+    let qualified = instance.name();
+    assert_eq!(&trimmed, expected_trimmed);
+    assert_eq!(&qualified, expected_qualified);
+
+    let item = CrateItem::try_from(instance).unwrap();
+    let trimmed = item.trimmed_name();
+    let qualified = item.name();
+    assert_eq!(trimmed, expected_trimmed.replace("u8", "T"));
+    assert_eq!(qualified, expected_qualified.replace("u8", "T"));
+    assert_eq!(&item.krate().name, krate);
+}
+
+/// Inspect the instance body
+fn get_instances(body: mir::Body) -> Vec<Instance> {
+    body.blocks.iter().filter_map(|bb| {
+        match &bb.terminator.kind {
+            Call { func, .. } => {
+                let TyKind::RigidTy(ty) = func.ty(body.locals()).unwrap().kind() else { unreachable!
+                () };
+                let RigidTy::FnDef(def, args) = ty else { unreachable!() };
+                Instance::resolve(def, &args).ok()
+            }
+            _ => {
+                None
+            }
+        }
+    }).collect::<Vec<_>>()
+}
+
+/// 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_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, 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#"
+
+        fn main() {{
+            let _c = core::char::from_u32(99);
+            let _v = Vec::<u8>::new();
+        }}
+    "#
+    )?;
+    Ok(())
+}
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 4164f041022..c2035430a33 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -23,6 +23,7 @@ use rustc_hir::def::DefKind;
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
 use stable_mir::ItemKind;
+use stable_mir::crate_def::CrateDef;
 use stable_mir::mir::mono::Instance;
 use stable_mir::ty::{RigidTy, TyKind};
 use std::assert_matches::assert_matches;
diff --git a/tests/ui-fulldeps/stable-mir/projections.rs b/tests/ui-fulldeps/stable-mir/projections.rs
index 29930763591..8c3fda7b6bb 100644
--- a/tests/ui-fulldeps/stable-mir/projections.rs
+++ b/tests/ui-fulldeps/stable-mir/projections.rs
@@ -21,6 +21,7 @@ extern crate stable_mir;
 
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
+use stable_mir::crate_def::CrateDef;
 use stable_mir::mir::{ProjectionElem, Rvalue, StatementKind};
 use stable_mir::ty::{RigidTy, TyKind, UintTy};
 use stable_mir::ItemKind;