rustc_smir/stable_mir/
mod.rs

1//! Module that is temporarily parasitic on the `rustc_smir` crate,
2//!
3//! This module is designed to resolve circular dependency that would happen
4//! if we gradually invert the dependency order between `rustc_smir` and `stable_mir`.
5//!
6//! Once refactoring is complete, we will migrate it back to the `stable_mir` crate.
7
8//! The WIP stable interface to rustc internals.
9//!
10//! For more information see <https://github.com/rust-lang/project-stable-mir>
11//!
12//! # Note
13//!
14//! This API is still completely unstable and subject to change.
15
16// #![doc(
17//     html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
18//     test(attr(allow(unused_variables), deny(warnings)))
19// )]
20//!
21//! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to
22//! interact with the compiler.
23//!
24//! The goal is to eventually be published on
25//! [crates.io](https://crates.io).
26
27use std::fmt::Debug;
28use std::{fmt, io};
29
30use serde::Serialize;
31use stable_mir::compiler_interface::with;
32pub use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId};
33pub use stable_mir::error::*;
34use stable_mir::mir::mono::StaticDef;
35use stable_mir::mir::{Body, Mutability};
36use stable_mir::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
37
38use crate::stable_mir;
39
40pub mod abi;
41#[macro_use]
42pub mod crate_def;
43pub mod compiler_interface;
44#[macro_use]
45pub mod error;
46pub mod mir;
47pub mod target;
48pub mod ty;
49pub mod visitor;
50
51/// Use String for now but we should replace it.
52pub type Symbol = String;
53
54/// The number that identifies a crate.
55pub type CrateNum = usize;
56
57impl Debug for DefId {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        f.debug_struct("DefId").field("id", &self.0).field("name", &self.name()).finish()
60    }
61}
62
63impl IndexedVal for DefId {
64    fn to_val(index: usize) -> Self {
65        DefId(index)
66    }
67
68    fn to_index(&self) -> usize {
69        self.0
70    }
71}
72
73/// A list of crate items.
74pub type CrateItems = Vec<CrateItem>;
75
76/// A list of trait decls.
77pub type TraitDecls = Vec<TraitDef>;
78
79/// A list of impl trait decls.
80pub type ImplTraitDecls = Vec<ImplDef>;
81
82/// A list of associated items.
83pub type AssocItems = Vec<AssocItem>;
84
85/// Holds information about a crate.
86#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
87pub struct Crate {
88    pub id: CrateNum,
89    pub name: Symbol,
90    pub is_local: bool,
91}
92
93impl Crate {
94    /// The list of foreign modules in this crate.
95    pub fn foreign_modules(&self) -> Vec<ForeignModuleDef> {
96        with(|cx| cx.foreign_modules(self.id))
97    }
98
99    /// The list of traits declared in this crate.
100    pub fn trait_decls(&self) -> TraitDecls {
101        with(|cx| cx.trait_decls(self.id))
102    }
103
104    /// The list of trait implementations in this crate.
105    pub fn trait_impls(&self) -> ImplTraitDecls {
106        with(|cx| cx.trait_impls(self.id))
107    }
108
109    /// Return a list of function definitions from this crate independent on their visibility.
110    pub fn fn_defs(&self) -> Vec<FnDef> {
111        with(|cx| cx.crate_functions(self.id))
112    }
113
114    /// Return a list of static items defined in this crate independent on their visibility.
115    pub fn statics(&self) -> Vec<StaticDef> {
116        with(|cx| cx.crate_statics(self.id))
117    }
118}
119
120#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
121pub enum ItemKind {
122    Fn,
123    Static,
124    Const,
125    Ctor(CtorKind),
126}
127
128#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
129pub enum CtorKind {
130    Const,
131    Fn,
132}
133
134pub type Filename = String;
135
136crate_def_with_ty! {
137    /// Holds information about an item in a crate.
138    #[derive(Serialize)]
139    pub CrateItem;
140}
141
142impl CrateItem {
143    /// This will return the body of an item or panic if it's not available.
144    pub fn expect_body(&self) -> mir::Body {
145        with(|cx| cx.mir_body(self.0))
146    }
147
148    /// Return the body of an item if available.
149    pub fn body(&self) -> Option<mir::Body> {
150        with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
151    }
152
153    /// Check if a body is available for this item.
154    pub fn has_body(&self) -> bool {
155        with(|cx| cx.has_body(self.0))
156    }
157
158    pub fn span(&self) -> Span {
159        with(|cx| cx.span_of_an_item(self.0))
160    }
161
162    pub fn kind(&self) -> ItemKind {
163        with(|cx| cx.item_kind(*self))
164    }
165
166    pub fn requires_monomorphization(&self) -> bool {
167        with(|cx| cx.requires_monomorphization(self.0))
168    }
169
170    pub fn ty(&self) -> Ty {
171        with(|cx| cx.def_ty(self.0))
172    }
173
174    pub fn is_foreign_item(&self) -> bool {
175        with(|cx| cx.is_foreign_item(self.0))
176    }
177
178    /// Emit MIR for this item body.
179    pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
180        self.body()
181            .ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
182            .dump(w, &self.name())
183    }
184}
185
186/// Return the function where execution starts if the current
187/// crate defines that. This is usually `main`, but could be
188/// `start` if the crate is a no-std crate.
189pub fn entry_fn() -> Option<CrateItem> {
190    with(|cx| cx.entry_fn())
191}
192
193/// Access to the local crate.
194pub fn local_crate() -> Crate {
195    with(|cx| cx.local_crate())
196}
197
198/// Try to find a crate or crates if multiple crates exist from given name.
199pub fn find_crates(name: &str) -> Vec<Crate> {
200    with(|cx| cx.find_crates(name))
201}
202
203/// Try to find a crate with the given name.
204pub fn external_crates() -> Vec<Crate> {
205    with(|cx| cx.external_crates())
206}
207
208/// Retrieve all items in the local crate that have a MIR associated with them.
209pub fn all_local_items() -> CrateItems {
210    with(|cx| cx.all_local_items())
211}
212
213pub fn all_trait_decls() -> TraitDecls {
214    with(|cx| cx.all_trait_decls())
215}
216
217pub fn all_trait_impls() -> ImplTraitDecls {
218    with(|cx| cx.all_trait_impls())
219}
220
221/// A type that provides internal information but that can still be used for debug purpose.
222#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
223pub struct Opaque(String);
224
225impl std::fmt::Display for Opaque {
226    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
227        write!(f, "{}", self.0)
228    }
229}
230
231impl std::fmt::Debug for Opaque {
232    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
233        write!(f, "{}", self.0)
234    }
235}
236
237pub fn opaque<T: Debug>(value: &T) -> Opaque {
238    Opaque(format!("{value:?}"))
239}