diff --git a/Cargo.lock b/Cargo.lock index e67fe08feec..014e14e5399 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3245,6 +3245,7 @@ dependencies = [ "rustc_driver", "rustc_driver_impl", "rustc_smir", + "stable_mir", ] [[package]] @@ -4409,7 +4410,7 @@ dependencies = [ "rustc_session", "rustc_span", "rustc_target", - "scoped-tls", + "stable_mir", "tracing", ] @@ -4946,6 +4947,14 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "stable_mir" +version = "0.1.0-preview" +dependencies = [ + "scoped-tls", + "tracing", +] + [[package]] name = "stacker" version = "0.1.15" diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml index 41003ad83f3..dcb165f9fdb 100644 --- a/compiler/rustc/Cargo.toml +++ b/compiler/rustc/Cargo.toml @@ -13,6 +13,7 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" } # Make sure rustc_smir ends up in the sysroot, because this # crate is intended to be used by stable MIR consumers, which are not in-tree rustc_smir = { path = "../rustc_smir" } +stable_mir = { path = "../stable_mir" } [dependencies.jemalloc-sys] version = "0.5.0" diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index 21ec904e43c..4c29f743708 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -4,24 +4,14 @@ version = "0.0.0" edition = "2021" [dependencies] -# Use optional dependencies for rustc_* in order to support building this crate separately. -rustc_hir = { path = "../rustc_hir", optional = true } -rustc_middle = { path = "../rustc_middle", optional = true } -rustc_span = { path = "../rustc_span", optional = true } -rustc_target = { path = "../rustc_target", optional = true } -rustc_driver = { path = "../rustc_driver", optional = true } -rustc_interface = { path = "../rustc_interface", optional = true} -rustc_session = {path = "../rustc_session", optional = true} +rustc_hir = { path = "../rustc_hir" } +rustc_middle = { path = "../rustc_middle" } +rustc_span = { path = "../rustc_span" } +rustc_target = { path = "../rustc_target" } +rustc_driver = { path = "../rustc_driver" } +rustc_interface = { path = "../rustc_interface" } +rustc_session = {path = "../rustc_session" } tracing = "0.1" -scoped-tls = "1.0" +stable_mir = {path = "../stable_mir" } [features] -default = [ - "rustc_hir", - "rustc_middle", - "rustc_span", - "rustc_target", - "rustc_driver", - "rustc_interface", - "rustc_session", -] diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs index 8cb533c8d67..b6c36678db5 100644 --- a/compiler/rustc_smir/src/lib.rs +++ b/compiler/rustc_smir/src/lib.rs @@ -10,26 +10,12 @@ html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/", test(attr(allow(unused_variables), deny(warnings))) )] -#![cfg_attr(not(feature = "default"), feature(rustc_private))] +#![feature(rustc_private)] #![feature(ptr_metadata)] #![feature(type_alias_impl_trait)] // Used to define opaque types. #![feature(intra_doc_pointers)] -// Declare extern rustc_* crates to enable building this crate separately from the compiler. -#[cfg(not(feature = "default"))] -extern crate rustc_hir; -#[cfg(not(feature = "default"))] -extern crate rustc_middle; -#[cfg(not(feature = "default"))] -extern crate rustc_span; -#[cfg(not(feature = "default"))] -extern crate rustc_target; - pub mod rustc_internal; -pub mod stable_mir; // Make this module private for now since external users should not call these directly. mod rustc_smir; - -#[macro_use] -extern crate scoped_tls; diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 10ee5af86c6..441aafd1257 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -3,75 +3,17 @@ //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs //! until stable MIR is complete. -use std::fmt::Debug; use std::ops::{ControlFlow, Index}; use crate::rustc_internal; -use crate::stable_mir::CompilerError; -use crate::{ - rustc_smir::Tables, - stable_mir::{self, with}, -}; +use crate::rustc_smir::Tables; use rustc_driver::{Callbacks, Compilation, RunCompiler}; use rustc_interface::{interface, Queries}; use rustc_middle::mir::interpret::AllocId; use rustc_middle::ty::TyCtxt; pub use rustc_span::def_id::{CrateNum, DefId}; use rustc_span::Span; - -fn with_tables(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R { - let mut ret = None; - with(|tables| tables.rustc_tables(&mut |t| ret = Some(f(t)))); - ret.unwrap() -} - -pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId { - with_tables(|t| t[item.0]) -} - -pub fn crate_item(did: DefId) -> stable_mir::CrateItem { - with_tables(|t| t.crate_item(did)) -} - -pub fn adt_def(did: DefId) -> stable_mir::ty::AdtDef { - with_tables(|t| t.adt_def(did)) -} - -pub fn foreign_def(did: DefId) -> stable_mir::ty::ForeignDef { - with_tables(|t| t.foreign_def(did)) -} - -pub fn fn_def(did: DefId) -> stable_mir::ty::FnDef { - with_tables(|t| t.fn_def(did)) -} - -pub fn closure_def(did: DefId) -> stable_mir::ty::ClosureDef { - with_tables(|t| t.closure_def(did)) -} - -pub fn generator_def(did: DefId) -> stable_mir::ty::GeneratorDef { - with_tables(|t| t.generator_def(did)) -} - -pub fn alias_def(did: DefId) -> stable_mir::ty::AliasDef { - with_tables(|t| t.alias_def(did)) -} - -pub fn param_def(did: DefId) -> stable_mir::ty::ParamDef { - with_tables(|t| t.param_def(did)) -} - -pub fn br_named_def(did: DefId) -> stable_mir::ty::BrNamedDef { - with_tables(|t| t.br_named_def(did)) -} - -pub fn trait_def(did: DefId) -> stable_mir::ty::TraitDef { - with_tables(|t| t.trait_def(did)) -} - -pub fn impl_def(did: DefId) -> stable_mir::ty::ImplDef { - with_tables(|t| t.impl_def(did)) -} +use stable_mir::CompilerError; impl<'tcx> Index for Tables<'tcx> { type Output = DefId; @@ -82,6 +24,15 @@ fn index(&self, index: stable_mir::DefId) -> &Self::Output { } } +impl<'tcx> Index for Tables<'tcx> { + type Output = Span; + + #[inline(always)] + fn index(&self, index: stable_mir::ty::Span) -> &Self::Output { + &self.spans[index.0] + } +} + impl<'tcx> Tables<'tcx> { pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem { stable_mir::CrateItem(self.create_def_id(did)) @@ -178,32 +129,12 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum { } pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) { - crate::stable_mir::run( + stable_mir::run( Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] }, f, ); } -/// A type that provides internal information but that can still be used for debug purpose. -#[derive(Clone)] -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(crate) fn opaque(value: &T) -> Opaque { - Opaque(format!("{value:?}")) -} - pub struct StableMir where B: Send, diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index d8766cf8ce2..63a2a145069 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -3,11 +3,9 @@ ConstValue, }; -use crate::{ - rustc_smir::{Stable, Tables}, - stable_mir::mir::Mutability, - stable_mir::ty::{Allocation, ProvenanceMap}, -}; +use crate::rustc_smir::{Stable, Tables}; +use stable_mir::mir::Mutability; +use stable_mir::ty::{Allocation, ProvenanceMap}; /// Creates new empty `Allocation` from given `Align`. fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation { diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index b575445c4d5..5ff17613b4e 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -7,19 +7,16 @@ //! //! For now, we are developing everything inside `rustc`, thus, we keep this module private. -use crate::rustc_internal::{self, opaque}; -use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; -use crate::stable_mir::ty::{ - FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy, -}; -use crate::stable_mir::{self, CompilerError, Context}; +use hir::def::DefKind; use rustc_hir as hir; use rustc_middle::mir; use rustc_middle::mir::interpret::{alloc_range, AllocId}; use rustc_middle::ty::{self, Ty, TyCtxt, Variance}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; -use rustc_span::ErrorGuaranteed; use rustc_target::abi::FieldIdx; +use stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; +use stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy}; +use stable_mir::{self, opaque, Context}; use tracing::debug; mod alloc; @@ -44,6 +41,14 @@ fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String { self.tcx.def_path_str(self[def_id]) } + fn print_span(&self, span: stable_mir::ty::Span) -> String { + self.tcx.sess.source_map().span_to_diagnostic_string(self[span]) + } + + fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind { + self.tcx.def_kind(self[def_id]).stable(self) + } + fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> Span { self.tcx.def_span(self[def_id]).stable(self) } @@ -104,11 +109,7 @@ fn mir_body(&mut self, item: stable_mir::DefId) -> stable_mir::mir::Body { } } - fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)) { - f(self) - } - - fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind { + fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind { self.types[ty.0].clone().stable(self) } @@ -276,7 +277,7 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { place.stable(tables), ), ThreadLocalRef(def_id) => { - stable_mir::mir::Rvalue::ThreadLocalRef(rustc_internal::crate_item(*def_id)) + stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id)) } AddressOf(mutability, place) => { stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables)) @@ -739,7 +740,7 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple, mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => { stable_mir::mir::AggregateKind::Adt( - rustc_internal::adt_def(*def_id), + tables.adt_def(*def_id), var_idx.index(), generic_arg.stable(tables), user_ty_index.map(|idx| idx.index()), @@ -748,13 +749,13 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { } mir::AggregateKind::Closure(def_id, generic_arg) => { stable_mir::mir::AggregateKind::Closure( - rustc_internal::closure_def(*def_id), + tables.closure_def(*def_id), generic_arg.stable(tables), ) } mir::AggregateKind::Generator(def_id, generic_arg, movability) => { stable_mir::mir::AggregateKind::Generator( - rustc_internal::generator_def(*def_id), + tables.generator_def(*def_id), generic_arg.stable(tables), movability.stable(tables), ) @@ -964,13 +965,13 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { impl<'tcx> Stable<'tcx> for ty::BoundTyKind { type T = stable_mir::ty::BoundTyKind; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::BoundTyKind; match self { ty::BoundTyKind::Anon => BoundTyKind::Anon, ty::BoundTyKind::Param(def_id, symbol) => { - BoundTyKind::Param(rustc_internal::param_def(*def_id), symbol.to_string()) + BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string()) } } } @@ -979,13 +980,13 @@ fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { impl<'tcx> Stable<'tcx> for ty::BoundRegionKind { type T = stable_mir::ty::BoundRegionKind; - fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::BoundRegionKind; match self { ty::BoundRegionKind::BrAnon => BoundRegionKind::BrAnon, ty::BoundRegionKind::BrNamed(def_id, symbol) => { - BoundRegionKind::BrNamed(rustc_internal::br_named_def(*def_id), symbol.to_string()) + BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string()) } ty::BoundRegionKind::BrEnv => BoundRegionKind::BrEnv, } @@ -1072,12 +1073,10 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))), ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))), ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt( - rustc_internal::adt_def(adt_def.did()), + tables.adt_def(adt_def.did()), generic_args.stable(tables), )), - ty::Foreign(def_id) => { - TyKind::RigidTy(RigidTy::Foreign(rustc_internal::foreign_def(*def_id))) - } + ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))), ty::Str => TyKind::RigidTy(RigidTy::Str), ty::Array(ty, constant) => { TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), constant.stable(tables))) @@ -1091,10 +1090,9 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { tables.intern_ty(*ty), mutbl.stable(tables), )), - ty::FnDef(def_id, generic_args) => TyKind::RigidTy(RigidTy::FnDef( - rustc_internal::fn_def(*def_id), - generic_args.stable(tables), - )), + ty::FnDef(def_id, generic_args) => { + TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables))) + } ty::FnPtr(poly_fn_sig) => TyKind::RigidTy(RigidTy::FnPtr(poly_fn_sig.stable(tables))), ty::Dynamic(existential_predicates, region, dyn_kind) => { TyKind::RigidTy(RigidTy::Dynamic( @@ -1107,11 +1105,11 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { )) } ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure( - rustc_internal::closure_def(*def_id), + tables.closure_def(*def_id), generic_args.stable(tables), )), ty::Generator(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Generator( - rustc_internal::generator_def(*def_id), + tables.generator_def(*def_id), generic_args.stable(tables), movability.stable(tables), )), @@ -1223,7 +1221,7 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::TraitDecl; TraitDecl { - def_id: rustc_internal::trait_def(self.def_id), + def_id: tables.trait_def(self.def_id), unsafety: self.unsafety.stable(tables), paren_sugar: self.paren_sugar, has_auto_impl: self.has_auto_impl, @@ -1272,7 +1270,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> { fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { use stable_mir::ty::TraitRef; - TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) } + TraitRef { def_id: tables.trait_def(self.def_id), args: self.args.stable(tables) } } } @@ -1516,8 +1514,11 @@ fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { } } -impl From for CompilerError { - fn from(_error: ErrorGuaranteed) -> Self { - CompilerError::CompilationFailed +impl<'tcx> Stable<'tcx> for DefKind { + type T = stable_mir::DefKind; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + // FIXME: add a real implementation of stable DefKind + opaque(self) } } diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml new file mode 100644 index 00000000000..c61e217bf9f --- /dev/null +++ b/compiler/stable_mir/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "stable_mir" +version = "0.1.0-preview" +edition = "2021" + +[dependencies] +tracing = "0.1" +scoped-tls = "1.0" diff --git a/compiler/rustc_smir/README.md b/compiler/stable_mir/README.md similarity index 100% rename from compiler/rustc_smir/README.md rename to compiler/stable_mir/README.md diff --git a/compiler/rustc_smir/rust-toolchain.toml b/compiler/stable_mir/rust-toolchain.toml similarity index 100% rename from compiler/rustc_smir/rust-toolchain.toml rename to compiler/stable_mir/rust-toolchain.toml diff --git a/compiler/rustc_smir/src/stable_mir/fold.rs b/compiler/stable_mir/src/fold.rs similarity index 99% rename from compiler/rustc_smir/src/stable_mir/fold.rs rename to compiler/stable_mir/src/fold.rs index 831cfb40a15..16ae62311aa 100644 --- a/compiler/rustc_smir/src/stable_mir/fold.rs +++ b/compiler/stable_mir/src/fold.rs @@ -1,6 +1,6 @@ use std::ops::ControlFlow; -use crate::rustc_internal::Opaque; +use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind, diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/stable_mir/src/lib.rs similarity index 76% rename from compiler/rustc_smir/src/stable_mir/mod.rs rename to compiler/stable_mir/src/lib.rs index 3c86cb4038a..104985493ef 100644 --- a/compiler/rustc_smir/src/stable_mir/mod.rs +++ b/compiler/stable_mir/src/lib.rs @@ -1,15 +1,21 @@ -//! Module that implements the public interface to the Stable MIR. +//! The WIP stable interface to rustc internals. //! -//! This module shall contain all type definitions and APIs that we expect third-party tools to invoke to +//! 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 move this module to its own crate which shall be published on +//! The goal is to eventually be published on //! [crates.io](https://crates.io). -//! -//! ## Note: -//! -//! There shouldn't be any direct references to internal compiler constructs in this module. -//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`. use std::cell::Cell; use std::fmt; @@ -18,7 +24,9 @@ use self::ty::{ GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind, }; -use crate::rustc_smir::Tables; + +#[macro_use] +extern crate scoped_tls; pub mod fold; pub mod mir; @@ -33,11 +41,11 @@ /// A unique identification number for each item accessible for the current compilation unit. #[derive(Clone, Copy, PartialEq, Eq)] -pub struct DefId(pub(crate) usize); +pub struct DefId(pub usize); impl Debug for DefId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("DefId:") + f.debug_struct("DefId") .field("id", &self.0) .field("name", &with(|cx| cx.name_of_def_id(*self))) .finish() @@ -46,7 +54,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { /// A unique identification number for each provenance #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct AllocId(pub(crate) usize); +pub struct AllocId(pub usize); /// A list of crate items. pub type CrateItems = Vec; @@ -74,16 +82,18 @@ pub enum CompilerError { /// Holds information about a crate. #[derive(Clone, PartialEq, Eq, Debug)] pub struct Crate { - pub(crate) id: CrateNum, + pub id: CrateNum, pub name: Symbol, pub is_local: bool, } +pub type DefKind = Opaque; + /// Holds information about an item in the crate. /// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to /// use this item. #[derive(Clone, PartialEq, Eq, Debug)] -pub struct CrateItem(pub(crate) DefId); +pub struct CrateItem(pub DefId); impl CrateItem { pub fn body(&self) -> mir::Body { @@ -93,6 +103,14 @@ pub fn body(&self) -> mir::Body { pub fn span(&self) -> Span { 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) -> DefKind { + with(|cx| cx.def_kind(self.0)) + } } /// Return the function where execution starts if the current @@ -161,6 +179,12 @@ pub trait Context { /// Prints the name of given `DefId` fn name_of_def_id(&self, def_id: DefId) -> String; + /// Prints a human readable form of `Span` + fn print_span(&self, span: Span) -> String; + + /// Prints the kind of given `DefId` + fn def_kind(&mut self, def_id: DefId) -> DefKind; + /// `Span` of an item fn span_of_an_item(&mut self, def_id: DefId) -> Span; @@ -169,10 +193,6 @@ pub trait Context { /// Create a new `Ty` from scratch without information from rustc. fn mk_ty(&mut self, kind: TyKind) -> Ty; - - /// HACK: Until we have fully stable consumers, we need an escape hatch - /// to get `DefId`s out of `CrateItem`s. - fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)); } // A thread local variable that stores a pointer to the tables mapping between TyCtxt @@ -192,7 +212,7 @@ fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) { /// Loads the current context and calls a function with it. /// Do not nest these, as that will ICE. -pub(crate) fn with(f: impl FnOnce(&mut dyn Context) -> R) -> R { +pub fn with(f: impl FnOnce(&mut dyn Context) -> R) -> R { assert!(TLV.is_set()); TLV.with(|tlv| { let ptr = tlv.get(); @@ -200,3 +220,23 @@ pub(crate) fn with(f: impl FnOnce(&mut dyn Context) -> R) -> R { f(unsafe { *(ptr as *mut &mut dyn Context) }) }) } + +/// A type that provides internal information but that can still be used for debug purpose. +#[derive(Clone)] +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:?}")) +} diff --git a/compiler/rustc_smir/src/stable_mir/mir.rs b/compiler/stable_mir/src/mir.rs similarity index 100% rename from compiler/rustc_smir/src/stable_mir/mir.rs rename to compiler/stable_mir/src/mir.rs diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/stable_mir/src/mir/body.rs similarity index 94% rename from compiler/rustc_smir/src/stable_mir/mir/body.rs rename to compiler/stable_mir/src/mir/body.rs index 449ca4b8145..6f8f7b06fa3 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -1,8 +1,6 @@ -use crate::rustc_internal::Opaque; -use crate::stable_mir::ty::{ - AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region, -}; -use crate::stable_mir::{self, ty::Ty, Span}; +use crate::ty::{AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region}; +use crate::Opaque; +use crate::{ty::Ty, Span}; #[derive(Clone, Debug)] pub struct Body { @@ -135,7 +133,7 @@ pub enum AsyncGeneratorKind { } pub(crate) type LocalDefId = Opaque; -/// [`rustc_middle::mir::Coverage`] is heavily tied to internal details of the +/// The rustc coverage data structures are heavily tied to internal details of the /// coverage implementation that are likely to change, and are unlikely to be /// useful to third-party tools for the foreseeable future. pub(crate) type Coverage = Opaque; @@ -215,7 +213,7 @@ pub enum Rvalue { /// generator lowering, `Generator` aggregate kinds are disallowed too. Aggregate(AggregateKind, Vec), - /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second + /// * `Offset` has the same semantics as `<*const T>::offset`, except that the second /// parameter may be a `usize` as well. /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats, /// raw pointers, or function pointers and return a `bool`. The types of the operands must be @@ -245,16 +243,14 @@ pub enum Rvalue { /// deref operation, immediately followed by one or more projections. CopyForDeref(Place), - /// Computes the discriminant of the place, returning it as an integer of type - /// [`discriminant_ty`]. Returns zero for types without discriminant. + /// Computes the discriminant of the place, returning it as an integer. + /// Returns zero for types without discriminant. /// /// The validity requirements for the underlying value are undecided for this rvalue, see /// [#91095]. Note too that the value of the discriminant is not the same thing as the - /// variant index; use [`discriminant_for_variant`] to convert. + /// variant index; /// - /// [`discriminant_ty`]: rustc_middle::ty::Ty::discriminant_ty /// [#91095]: https://github.com/rust-lang/rust/issues/91095 - /// [`discriminant_for_variant`]: rustc_middle::ty::Ty::discriminant_for_variant Discriminant(Place), /// Yields the length of the place, as a `usize`. @@ -295,7 +291,7 @@ pub enum Rvalue { /// /// **Needs clarification**: Are there weird additional semantics here related to the runtime /// nature of this operation? - ThreadLocalRef(stable_mir::CrateItem), + ThreadLocalRef(crate::CrateItem), /// Computes a value as described by the operation. NullaryOp(NullOp, Ty), diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/stable_mir/src/ty.rs similarity index 92% rename from compiler/rustc_smir/src/stable_mir/ty.rs rename to compiler/stable_mir/src/ty.rs index eb9967b3888..82007e30683 100644 --- a/compiler/rustc_smir/src/stable_mir/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -3,7 +3,7 @@ mir::{Body, Mutability}, with, AllocId, DefId, }; -use crate::rustc_internal::Opaque; +use crate::Opaque; use std::fmt::{self, Debug, Formatter}; #[derive(Copy, Clone)] @@ -34,15 +34,16 @@ pub struct Const { } type Ident = Opaque; -pub(crate) type Region = Opaque; +pub type Region = Opaque; #[derive(Clone, Copy, PartialEq, Eq)] -pub struct Span(pub(crate) usize); +pub struct Span(pub usize); impl Debug for Span { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let mut span = None; - with(|context| context.rustc_tables(&mut |tables| span = Some(tables.spans[self.0]))); - f.write_fmt(format_args!("{:?}", &span.unwrap())) + f.debug_struct("Span") + .field("id", &self.0) + .field("repr", &with(|cx| cx.print_span(*self))) + .finish() } } @@ -110,10 +111,10 @@ pub enum Movability { } #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct ForeignDef(pub(crate) DefId); +pub struct ForeignDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct FnDef(pub(crate) DefId); +pub struct FnDef(pub DefId); impl FnDef { pub fn body(&self) -> Body { @@ -122,34 +123,34 @@ pub fn body(&self) -> Body { } #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct ClosureDef(pub(crate) DefId); +pub struct ClosureDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct GeneratorDef(pub(crate) DefId); +pub struct GeneratorDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct ParamDef(pub(crate) DefId); +pub struct ParamDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct BrNamedDef(pub(crate) DefId); +pub struct BrNamedDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct AdtDef(pub(crate) DefId); +pub struct AdtDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct AliasDef(pub(crate) DefId); +pub struct AliasDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct TraitDef(pub(crate) DefId); +pub struct TraitDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct GenericDef(pub(crate) DefId); +pub struct GenericDef(pub DefId); #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct ConstDef(pub(crate) DefId); +pub struct ConstDef(pub DefId); #[derive(Clone, PartialEq, Eq, Debug)] -pub struct ImplDef(pub(crate) DefId); +pub struct ImplDef(pub DefId); #[derive(Clone, Debug)] pub struct GenericArgs(pub Vec); @@ -333,7 +334,7 @@ pub struct BoundTy { pub type Size = usize; #[derive(Clone, Copy, PartialEq, Eq, Debug)] -pub struct Prov(pub(crate) AllocId); +pub struct Prov(pub AllocId); pub type Align = u64; pub type Promoted = u32; pub type InitMaskMaterialized = Vec; diff --git a/compiler/rustc_smir/src/stable_mir/visitor.rs b/compiler/stable_mir/src/visitor.rs similarity index 99% rename from compiler/rustc_smir/src/stable_mir/visitor.rs rename to compiler/stable_mir/src/visitor.rs index c86063d2ed6..9c3b4cd994a 100644 --- a/compiler/rustc_smir/src/stable_mir/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -1,6 +1,6 @@ use std::ops::ControlFlow; -use crate::rustc_internal::Opaque; +use crate::Opaque; use super::ty::{ Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 4f19ffa83db..292ccc5780f 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1789,7 +1789,10 @@ pub fn run_cargo( // During check builds we need to keep crate metadata keep = true; } else if rlib_only_metadata { - if filename.contains("jemalloc_sys") || filename.contains("rustc_smir") { + if filename.contains("jemalloc_sys") + || filename.contains("rustc_smir") + || filename.contains("stable_mir") + { // jemalloc_sys and rustc_smir are not linked into librustc_driver.so, // so we need to distribute them as rlib to be able to use them. keep |= filename.ends_with(".rlib"); diff --git a/tests/ui-fulldeps/stable-mir/compilation-result.rs b/tests/ui-fulldeps/stable-mir/compilation-result.rs index 23a9e2a064c..3ec1519fb13 100644 --- a/tests/ui-fulldeps/stable-mir/compilation-result.rs +++ b/tests/ui-fulldeps/stable-mir/compilation-result.rs @@ -11,9 +11,10 @@ extern crate rustc_middle; extern crate rustc_smir; +extern crate stable_mir; use rustc_middle::ty::TyCtxt; -use rustc_smir::{rustc_internal, stable_mir}; +use rustc_smir::rustc_internal; use std::io::Write; use std::ops::ControlFlow; diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index a11720c4b55..ce4ee3c2463 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -13,13 +13,13 @@ extern crate rustc_hir; extern crate rustc_middle; extern crate rustc_smir; +extern crate stable_mir; use rustc_hir::def::DefKind; use rustc_middle::ty::TyCtxt; -use rustc_smir::{ - rustc_internal, - stable_mir::{self, fold::Foldable}, -}; +use rustc_smir::rustc_internal; + +use stable_mir::fold::Foldable; use std::assert_matches::assert_matches; use std::io::Write; use std::ops::ControlFlow; @@ -27,7 +27,7 @@ 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<()> { +fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> { // Get the local crate using stable_mir API. let local = stable_mir::local_crate(); assert_eq!(&local.name, CRATE_NAME); @@ -36,12 +36,12 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { // Find items in the local crate. let items = stable_mir::all_local_items(); - assert!(get_item(tcx, &items, (DefKind::Fn, "foo::bar")).is_some()); + assert!(get_item(&items, (DefKind::Fn, "foo::bar")).is_some()); // Find the `std` crate. assert!(stable_mir::find_crate("std").is_some()); - let bar = get_item(tcx, &items, (DefKind::Fn, "bar")).unwrap(); + let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap(); let body = bar.body(); assert_eq!(body.locals.len(), 2); assert_eq!(body.blocks.len(), 1); @@ -56,7 +56,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { other => panic!("{other:?}"), } - let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap(); + let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap(); let body = foo_bar.body(); assert_eq!(body.locals.len(), 7); assert_eq!(body.blocks.len(), 4); @@ -66,7 +66,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { other => panic!("{other:?}"), } - let types = get_item(tcx, &items, (DefKind::Fn, "types")).unwrap(); + let types = get_item(&items, (DefKind::Fn, "types")).unwrap(); let body = types.body(); assert_eq!(body.locals.len(), 6); assert_matches!( @@ -96,7 +96,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { )) ); - let drop = get_item(tcx, &items, (DefKind::Fn, "drop")).unwrap(); + let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap(); let body = drop.body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; @@ -105,7 +105,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { other => panic!("{other:?}"), } - let assert = get_item(tcx, &items, (DefKind::Fn, "assert")).unwrap(); + let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap(); let body = assert.body(); assert_eq!(body.blocks.len(), 2); let block = &body.blocks[0]; @@ -114,7 +114,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { other => panic!("{other:?}"), } - let monomorphic = get_item(tcx, &items, (DefKind::Fn, "monomorphic")).unwrap(); + let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap(); for block in monomorphic.body().blocks { match &block.terminator { stable_mir::mir::Terminator::Call { func, .. } => match func { @@ -154,7 +154,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { } } - let foo_const = get_item(tcx, &items, (DefKind::Const, "FOO")).unwrap(); + let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap(); // Ensure we don't panic trying to get the body of a constant. foo_const.body(); @@ -163,13 +163,11 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> { // Use internal API to find a function in a crate. fn get_item<'a>( - tcx: TyCtxt, items: &'a stable_mir::CrateItems, item: (DefKind, &str), ) -> Option<&'a stable_mir::CrateItem> { items.iter().find(|crate_item| { - let def_id = rustc_internal::item_def_id(crate_item); - tcx.def_kind(def_id) == item.0 && tcx.def_path_str(def_id) == item.1 + crate_item.kind().to_string() == format!("{:?}", item.0) && crate_item.name() == item.1 }) } diff --git a/triagebot.toml b/triagebot.toml index dbced481993..648997ad6f0 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -542,6 +542,10 @@ cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"] message = "This PR changes Stable MIR" cc = ["@oli-obk", "@celinval", "@spastorino"] +[mentions."compiler/stable_mir"] +message = "This PR changes Stable MIR" +cc = ["@oli-obk", "@celinval", "@spastorino"] + [mentions."compiler/rustc_target/src/spec"] message = """ These commits modify **compiler targets**.