//! The WIP stable interface to rustc internals. //! //! For more information see //! //! # Note //! //! This API is still completely unstable and subject to change. #![doc( html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] //! //! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to //! interact with the compiler. //! //! The goal is to eventually be published on //! [crates.io](https://crates.io). #![feature(type_alias_impl_trait)] #[macro_use] extern crate scoped_tls; use std::fmt; use std::fmt::Debug; use std::io; use crate::compiler_interface::with; pub use crate::crate_def::CrateDef; pub use crate::crate_def::DefId; pub use crate::error::*; use crate::mir::pretty::function_name; use crate::mir::Body; use crate::mir::Mutability; use crate::ty::{ImplDef, ImplTrait, IndexedVal, Span, TraitDecl, TraitDef, Ty}; pub mod abi; #[macro_use] pub mod crate_def; pub mod compiler_interface; #[macro_use] pub mod error; pub mod mir; pub mod target; pub mod ty; pub mod visitor; /// Use String for now but we should replace it. pub type Symbol = String; /// The number that identifies a crate. pub type CrateNum = 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.def_name(*self, false))) .finish() } } impl IndexedVal for DefId { fn to_val(index: usize) -> Self { DefId(index) } fn to_index(&self) -> usize { self.0 } } /// A list of crate items. pub type CrateItems = Vec; /// A list of trait decls. pub type TraitDecls = Vec; /// A list of impl trait decls. pub type ImplTraitDecls = Vec; /// Holds information about a crate. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Crate { pub id: CrateNum, pub name: Symbol, pub is_local: bool, } #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] pub enum ItemKind { Fn, Static, Const, } pub type Filename = String; crate_def! { /// Holds information about an item in a crate. pub CrateItem; } impl CrateItem { pub fn body(&self) -> mir::Body { with(|cx| cx.mir_body(self.0)) } pub fn span(&self) -> Span { with(|cx| cx.span_of_an_item(self.0)) } pub fn kind(&self) -> ItemKind { with(|cx| cx.item_kind(*self)) } pub fn requires_monomorphization(&self) -> bool { with(|cx| cx.requires_monomorphization(self.0)) } pub fn ty(&self) -> Ty { with(|cx| cx.def_ty(self.0)) } pub fn is_foreign_item(&self) -> bool { with(|cx| cx.is_foreign_item(self.0)) } pub fn dump(&self, w: &mut W) -> io::Result<()> { writeln!(w, "{}", function_name(*self))?; self.body().dump(w) } } /// Return the function where execution starts if the current /// crate defines that. This is usually `main`, but could be /// `start` if the crate is a no-std crate. pub fn entry_fn() -> Option { with(|cx| cx.entry_fn()) } /// Access to the local crate. pub fn local_crate() -> Crate { with(|cx| cx.local_crate()) } /// Try to find a crate or crates if multiple crates exist from given name. pub fn find_crates(name: &str) -> Vec { with(|cx| cx.find_crates(name)) } /// Try to find a crate with the given name. pub fn external_crates() -> Vec { with(|cx| cx.external_crates()) } /// Retrieve all items in the local crate that have a MIR associated with them. pub fn all_local_items() -> CrateItems { with(|cx| cx.all_local_items()) } pub fn all_trait_decls() -> TraitDecls { with(|cx| cx.all_trait_decls()) } pub fn trait_decl(trait_def: &TraitDef) -> TraitDecl { with(|cx| cx.trait_decl(trait_def)) } pub fn all_trait_impls() -> ImplTraitDecls { with(|cx| cx.all_trait_impls()) } pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait { with(|cx| cx.trait_impl(trait_impl)) } /// A type that provides internal information but that can still be used for debug purpose. #[derive(Clone, PartialEq, Eq, Hash)] pub struct Opaque(String); impl std::fmt::Display for Opaque { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } impl std::fmt::Debug for Opaque { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", self.0) } } pub fn opaque(value: &T) -> Opaque { Opaque(format!("{value:?}")) }