stable_mir/
lib.rs

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