let rustc_smir host stable_mir for refactoring

This commit is contained in:
Makai 2025-04-05 18:23:07 +08:00
parent 1e008dd5d8
commit 707d356d00
31 changed files with 346 additions and 305 deletions

View file

@ -4432,7 +4432,7 @@ dependencies = [
"rustc_span",
"rustc_target",
"scoped-tls",
"stable_mir",
"serde",
"tracing",
]
@ -4990,8 +4990,7 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
name = "stable_mir"
version = "0.1.0-preview"
dependencies = [
"scoped-tls",
"serde",
"rustc_smir",
]
[[package]]

View file

@ -14,6 +14,6 @@ rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
scoped-tls = "1.0"
stable_mir = {path = "../stable_mir" }
serde = { version = "1.0.125", features = [ "derive" ] }
tracing = "0.1"
# tidy-alphabetical-end

View file

@ -22,3 +22,5 @@ pub mod rustc_internal;
// Make this module private for now since external users should not call these directly.
mod rustc_smir;
pub mod stable_mir;

View file

@ -21,6 +21,7 @@ use stable_mir::{CrateItem, CrateNum, DefId};
use super::RustcInternal;
use crate::rustc_smir::Tables;
use crate::stable_mir;
impl RustcInternal for CrateItem {
type T<'tcx> = rustc_span::def_id::DefId;

View file

@ -22,6 +22,7 @@ use stable_mir::ty::IndexedVal;
use crate::rustc_smir::context::TablesWrapper;
use crate::rustc_smir::{Stable, Tables};
use crate::stable_mir;
mod internal;
pub mod pretty;

View file

@ -3,6 +3,7 @@ use std::io;
use rustc_middle::ty::TyCtxt;
use super::run;
use crate::stable_mir;
pub fn write_smir_pretty<'tcx, W: io::Write>(tcx: TyCtxt<'tcx>, w: &mut W) -> io::Result<()> {
writeln!(

View file

@ -6,6 +6,7 @@ use stable_mir::mir::Mutability;
use stable_mir::ty::{Allocation, ProvenanceMap};
use crate::rustc_smir::{Stable, Tables};
use crate::stable_mir;
/// Creates new empty `Allocation` from given `Align`.
fn new_empty_allocation(align: Align) -> Allocation {

View file

@ -10,6 +10,7 @@ use rustc_middle::mir::visit::MutVisitor;
use rustc_middle::ty::{self, TyCtxt};
use crate::rustc_smir::{Stable, Tables};
use crate::stable_mir;
/// Builds a monomorphic body for a given instance.
pub(crate) struct BodyBuilder<'tcx> {

View file

@ -35,6 +35,7 @@ use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, I
use crate::rustc_internal::RustcInternal;
use crate::rustc_smir::builder::BodyBuilder;
use crate::rustc_smir::{Stable, Tables, alloc, filter_def_ids, new_item_kind, smir_crate};
use crate::stable_mir;
impl<'tcx> Context for TablesWrapper<'tcx> {
fn target_info(&self) -> MachineInfo {

View file

@ -14,6 +14,7 @@ use stable_mir::target::MachineSize as Size;
use stable_mir::ty::{Align, IndexedVal, VariantIdx};
use crate::rustc_smir::{Stable, Tables};
use crate::stable_mir;
impl<'tcx> Stable<'tcx> for rustc_abi::VariantIdx {
type T = VariantIdx;

View file

@ -6,6 +6,7 @@ use rustc_middle::mir::interpret::AllocError;
use rustc_middle::ty::layout::LayoutError;
use crate::rustc_smir::{Stable, Tables};
use crate::stable_mir;
impl<'tcx> Stable<'tcx> for LayoutError<'tcx> {
type T = stable_mir::Error;

View file

@ -9,6 +9,7 @@ use stable_mir::ty::{Allocation, ConstantKind, MirConst};
use stable_mir::{Error, opaque};
use crate::rustc_smir::{Stable, Tables, alloc};
use crate::stable_mir;
impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
type T = stable_mir::mir::Body;

View file

@ -3,6 +3,7 @@
use rustc_abi::FieldIdx;
use crate::rustc_smir::{Stable, Tables};
use crate::stable_mir;
mod abi;
mod error;

View file

@ -7,6 +7,7 @@ use stable_mir::ty::{
};
use crate::rustc_smir::{Stable, Tables, alloc};
use crate::stable_mir;
impl<'tcx> Stable<'tcx> for ty::AliasTyKind {
type T = stable_mir::ty::AliasKind;

View file

@ -21,6 +21,7 @@ use stable_mir::{CtorKind, ItemKind};
use tracing::debug;
use crate::rustc_internal::IndexMap;
use crate::stable_mir;
mod alloc;
mod builder;

View file

@ -3,12 +3,13 @@ use std::num::NonZero;
use std::ops::RangeInclusive;
use serde::Serialize;
use stable_mir::compiler_interface::with;
use stable_mir::mir::FieldIdx;
use stable_mir::target::{MachineInfo, MachineSize as Size};
use stable_mir::ty::{Align, IndexedVal, Ty, VariantIdx};
use stable_mir::{Error, Opaque, error};
use crate::compiler_interface::with;
use crate::mir::FieldIdx;
use crate::target::{MachineInfo, MachineSize as Size};
use crate::ty::{Align, IndexedVal, Ty, VariantIdx};
use crate::{Error, Opaque, error};
use crate::stable_mir;
/// A function ABI definition.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
@ -149,7 +150,7 @@ pub enum FieldsShape {
Arbitrary {
/// Offsets for the first byte of each field,
/// ordered to match the source definition order.
/// I.e.: It follows the same order as [crate::ty::VariantDef::fields()].
/// I.e.: It follows the same order as [super::ty::VariantDef::fields()].
/// This vector does not go in increasing order.
offsets: Vec<Size>,
},

View file

@ -5,23 +5,25 @@
use std::cell::Cell;
use crate::abi::{FnAbi, Layout, LayoutShape};
use crate::crate_def::Attribute;
use crate::mir::alloc::{AllocId, GlobalAlloc};
use crate::mir::mono::{Instance, InstanceDef, StaticDef};
use crate::mir::{BinOp, Body, Place, UnOp};
use crate::target::MachineInfo;
use crate::ty::{
use stable_mir::abi::{FnAbi, Layout, LayoutShape};
use stable_mir::crate_def::Attribute;
use stable_mir::mir::alloc::{AllocId, GlobalAlloc};
use stable_mir::mir::mono::{Instance, InstanceDef, StaticDef};
use stable_mir::mir::{BinOp, Body, Place, UnOp};
use stable_mir::target::MachineInfo;
use stable_mir::ty::{
AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef,
ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics,
ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl,
TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef,
};
use crate::{
use stable_mir::{
AssocItems, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls,
ItemKind, Symbol, TraitDecls, mir,
};
use crate::stable_mir;
/// This trait defines the interface between stable_mir and the Rust compiler.
/// Do not use this directly.
pub trait Context {

View file

@ -2,9 +2,10 @@
//! such as, a function, a trait, an enum, and any other definitions.
use serde::Serialize;
use stable_mir::ty::{GenericArgs, Span, Ty};
use stable_mir::{AssocItems, Crate, Symbol, with};
use crate::ty::{GenericArgs, Span, Ty};
use crate::{AssocItems, Crate, Symbol, with};
use crate::stable_mir;
/// A unique identification number for each item accessible for the current compilation unit.
#[derive(Clone, Copy, PartialEq, Eq, Hash, Serialize)]

View file

@ -3,11 +3,12 @@
use std::io::Read;
use serde::Serialize;
use stable_mir::mir::mono::{Instance, StaticDef};
use stable_mir::target::{Endian, MachineInfo};
use stable_mir::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
use stable_mir::{Error, with};
use crate::mir::mono::{Instance, StaticDef};
use crate::target::{Endian, MachineInfo};
use crate::ty::{Allocation, Binder, ExistentialTraitRef, IndexedVal, Ty};
use crate::{Error, with};
use crate::stable_mir;
/// An allocation in the SMIR global memory can be either a function pointer,
/// a static, or a "real" allocation with some data in it.

View file

@ -1,14 +1,15 @@
use std::io;
use serde::Serialize;
use crate::compiler_interface::with;
use crate::mir::pretty::function_body;
use crate::ty::{
use stable_mir::compiler_interface::with;
use stable_mir::mir::pretty::function_body;
use stable_mir::ty::{
AdtDef, ClosureDef, CoroutineClosureDef, CoroutineDef, GenericArgs, MirConst, Movability,
Region, RigidTy, Ty, TyConst, TyKind, VariantIdx,
};
use crate::{Error, Opaque, Span, Symbol};
use stable_mir::{Error, Opaque, Span, Symbol};
use crate::stable_mir;
/// The SMIR representation of a single function.
#[derive(Clone, Debug, Serialize)]
@ -565,7 +566,7 @@ pub enum Rvalue {
///
/// **Needs clarification**: Are there weird additional semantics here related to the runtime
/// nature of this operation?
ThreadLocalRef(crate::CrateItem),
ThreadLocalRef(stable_mir::CrateItem),
/// Computes a value as described by the operation.
NullaryOp(NullOp, Ty),

View file

@ -2,12 +2,13 @@ use std::fmt::{Debug, Formatter};
use std::io;
use serde::Serialize;
use stable_mir::abi::FnAbi;
use stable_mir::crate_def::CrateDef;
use stable_mir::mir::Body;
use stable_mir::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
use stable_mir::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, with};
use crate::abi::FnAbi;
use crate::crate_def::CrateDef;
use crate::mir::Body;
use crate::ty::{Allocation, ClosureDef, ClosureKind, FnDef, GenericArgs, IndexedVal, Ty};
use crate::{CrateItem, DefId, Error, ItemKind, Opaque, Symbol, with};
use crate::stable_mir;
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize)]
pub enum MonoItem {
@ -117,11 +118,11 @@ impl Instance {
}
/// Resolve an instance starting from a function definition and generic arguments.
pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> {
pub fn resolve(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
with(|context| {
context.resolve_instance(def, args).ok_or_else(|| {
crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
})
context
.resolve_instance(def, args)
.ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
})
}
@ -131,11 +132,11 @@ impl Instance {
}
/// Resolve an instance for a given function pointer.
pub fn resolve_for_fn_ptr(def: FnDef, args: &GenericArgs) -> Result<Instance, crate::Error> {
pub fn resolve_for_fn_ptr(def: FnDef, args: &GenericArgs) -> Result<Instance, Error> {
with(|context| {
context.resolve_for_fn_ptr(def, args).ok_or_else(|| {
crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
})
context
.resolve_for_fn_ptr(def, args)
.ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
})
}
@ -144,11 +145,11 @@ impl Instance {
def: ClosureDef,
args: &GenericArgs,
kind: ClosureKind,
) -> Result<Instance, crate::Error> {
) -> Result<Instance, Error> {
with(|context| {
context.resolve_closure(def, args, kind).ok_or_else(|| {
crate::Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`"))
})
context
.resolve_closure(def, args, kind)
.ok_or_else(|| Error::new(format!("Failed to resolve `{def:?}` with `{args:?}`")))
})
}
@ -195,7 +196,7 @@ impl Debug for Instance {
/// Try to convert a crate item into an instance.
/// The item cannot be generic in order to be converted into an instance.
impl TryFrom<CrateItem> for Instance {
type Error = crate::Error;
type Error = stable_mir::Error;
fn try_from(item: CrateItem) -> Result<Self, Self::Error> {
with(|context| {
@ -212,7 +213,7 @@ impl TryFrom<CrateItem> for Instance {
/// Try to convert an instance into a crate item.
/// Only user defined instances can be converted.
impl TryFrom<Instance> for CrateItem {
type Error = crate::Error;
type Error = stable_mir::Error;
fn try_from(value: Instance) -> Result<Self, Self::Error> {
with(|context| {
@ -259,7 +260,7 @@ crate_def! {
}
impl TryFrom<CrateItem> for StaticDef {
type Error = crate::Error;
type Error = stable_mir::Error;
fn try_from(value: CrateItem) -> Result<Self, Self::Error> {
if matches!(value.kind(), ItemKind::Static) {
@ -271,7 +272,7 @@ impl TryFrom<CrateItem> for StaticDef {
}
impl TryFrom<Instance> for StaticDef {
type Error = crate::Error;
type Error = stable_mir::Error;
fn try_from(value: Instance) -> Result<Self, Self::Error> {
StaticDef::try_from(CrateItem::try_from(value)?)

View file

@ -4,13 +4,14 @@ use std::io::Write;
use std::{fmt, io, iter};
use fmt::{Display, Formatter};
use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind};
use crate::mir::{
use stable_mir::mir::{
Operand, Place, RawPtrKind, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents,
};
use crate::ty::{AdtKind, AssocKind, IndexedVal, MirConst, Ty, TyConst};
use crate::{Body, CrateDef, Mutability, with};
use stable_mir::ty::{AdtKind, AssocKind, IndexedVal, MirConst, Ty, TyConst};
use stable_mir::{Body, CrateDef, Mutability, with};
use super::{AggregateKind, AssertMessage, BinOp, BorrowKind, FakeBorrowKind, TerminatorKind};
use crate::stable_mir;
impl Display for Ty {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {

View file

@ -35,9 +35,11 @@
//! The only place that `_` is acceptable is to match a field (or
//! variant argument) that does not require visiting.
use crate::mir::*;
use crate::ty::{GenericArgs, MirConst, Region, Ty, TyConst};
use crate::{Error, Opaque, Span};
use stable_mir::mir::*;
use stable_mir::ty::{GenericArgs, MirConst, Region, Ty, TyConst};
use stable_mir::{Error, Opaque, Span};
use crate::stable_mir;
macro_rules! make_mir_visitor {
($visitor_trait_name:ident, $($mutability:ident)?) => {

View file

@ -0,0 +1,239 @@
//! Module that is temporarily parasitic on the `rustc_smir` crate,
//!
//! This module is designed to resolve circular dependency that would happen
//! if we gradually invert the dependency order between `rustc_smir` and `stable_mir`.
//!
//! Once refactoring is complete, we will migrate it back to the `stable_mir` crate.
//! The WIP stable interface to rustc internals.
//!
//! For more information see <https://github.com/rust-lang/project-stable-mir>
//!
//! # 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).
use std::fmt::Debug;
use std::{fmt, io};
use serde::Serialize;
use stable_mir::compiler_interface::with;
pub use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId};
pub use stable_mir::error::*;
use stable_mir::mir::mono::StaticDef;
use stable_mir::mir::{Body, Mutability};
use stable_mir::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, TraitDef, Ty};
use crate::stable_mir;
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", &self.name()).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<CrateItem>;
/// A list of trait decls.
pub type TraitDecls = Vec<TraitDef>;
/// A list of impl trait decls.
pub type ImplTraitDecls = Vec<ImplDef>;
/// A list of associated items.
pub type AssocItems = Vec<AssocItem>;
/// Holds information about a crate.
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub struct Crate {
pub id: CrateNum,
pub name: Symbol,
pub is_local: bool,
}
impl Crate {
/// The list of foreign modules in this crate.
pub fn foreign_modules(&self) -> Vec<ForeignModuleDef> {
with(|cx| cx.foreign_modules(self.id))
}
/// The list of traits declared in this crate.
pub fn trait_decls(&self) -> TraitDecls {
with(|cx| cx.trait_decls(self.id))
}
/// The list of trait implementations in this crate.
pub fn trait_impls(&self) -> ImplTraitDecls {
with(|cx| cx.trait_impls(self.id))
}
/// Return a list of function definitions from this crate independent on their visibility.
pub fn fn_defs(&self) -> Vec<FnDef> {
with(|cx| cx.crate_functions(self.id))
}
/// Return a list of static items defined in this crate independent on their visibility.
pub fn statics(&self) -> Vec<StaticDef> {
with(|cx| cx.crate_statics(self.id))
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum ItemKind {
Fn,
Static,
Const,
Ctor(CtorKind),
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum CtorKind {
Const,
Fn,
}
pub type Filename = String;
crate_def_with_ty! {
/// Holds information about an item in a crate.
#[derive(Serialize)]
pub CrateItem;
}
impl CrateItem {
/// This will return the body of an item or panic if it's not available.
pub fn expect_body(&self) -> mir::Body {
with(|cx| cx.mir_body(self.0))
}
/// Return the body of an item if available.
pub fn body(&self) -> Option<mir::Body> {
with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
}
/// Check if a body is available for this item.
pub fn has_body(&self) -> bool {
with(|cx| cx.has_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))
}
/// Emit MIR for this item body.
pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
self.body()
.ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
.dump(w, &self.name())
}
}
/// 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<CrateItem> {
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<Crate> {
with(|cx| cx.find_crates(name))
}
/// Try to find a crate with the given name.
pub fn external_crates() -> Vec<Crate> {
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 all_trait_impls() -> ImplTraitDecls {
with(|cx| cx.all_trait_impls())
}
/// A type that provides internal information but that can still be used for debug purpose.
#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
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<T: Debug>(value: &T) -> Opaque {
Opaque(format!("{value:?}"))
}

View file

@ -1,8 +1,9 @@
//! Provide information about the machine that this is being compiled into.
use serde::Serialize;
use stable_mir::compiler_interface::with;
use crate::compiler_interface::with;
use crate::stable_mir;
/// The properties of the target machine being compiled into.
#[derive(Clone, PartialEq, Eq, Serialize)]

View file

@ -2,15 +2,16 @@ use std::fmt::{self, Debug, Display, Formatter};
use std::ops::Range;
use serde::Serialize;
use stable_mir::abi::{FnAbi, Layout};
use stable_mir::crate_def::{CrateDef, CrateDefItems, CrateDefType};
use stable_mir::mir::alloc::{AllocId, read_target_int, read_target_uint};
use stable_mir::mir::mono::StaticDef;
use stable_mir::target::MachineInfo;
use stable_mir::{Filename, Opaque};
use super::mir::{Body, Mutability, Safety};
use super::{DefId, Error, Symbol, with};
use crate::abi::{FnAbi, Layout};
use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType};
use crate::mir::alloc::{AllocId, read_target_int, read_target_uint};
use crate::mir::mono::StaticDef;
use crate::target::MachineInfo;
use crate::{Filename, Opaque};
use crate::stable_mir;
#[derive(Copy, Clone, Eq, PartialEq, Hash, Serialize)]
pub struct Ty(usize);
@ -588,7 +589,7 @@ pub enum IntTy {
impl IntTy {
pub fn num_bytes(self) -> usize {
match self {
IntTy::Isize => crate::target::MachineInfo::target_pointer_width().bytes(),
IntTy::Isize => MachineInfo::target_pointer_width().bytes(),
IntTy::I8 => 1,
IntTy::I16 => 2,
IntTy::I32 => 4,
@ -611,7 +612,7 @@ pub enum UintTy {
impl UintTy {
pub fn num_bytes(self) -> usize {
match self {
UintTy::Usize => crate::target::MachineInfo::target_pointer_width().bytes(),
UintTy::Usize => MachineInfo::target_pointer_width().bytes(),
UintTy::U8 => 1,
UintTy::U16 => 2,
UintTy::U32 => 4,

View file

@ -1,11 +1,13 @@
use std::ops::ControlFlow;
use stable_mir::Opaque;
use stable_mir::ty::TyConst;
use super::ty::{
Allocation, Binder, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
MirConst, Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
};
use crate::Opaque;
use crate::ty::TyConst;
use crate::stable_mir;
pub trait Visitor: Sized {
type Break;
@ -47,13 +49,13 @@ impl Visitable for TyConst {
}
fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
match &self.kind {
crate::ty::TyConstKind::Param(_) | crate::ty::TyConstKind::Bound(_, _) => {}
crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?,
crate::ty::TyConstKind::Value(ty, alloc) => {
super::ty::TyConstKind::Param(_) | super::ty::TyConstKind::Bound(_, _) => {}
super::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?,
super::ty::TyConstKind::Value(ty, alloc) => {
alloc.visit(visitor)?;
ty.visit(visitor)?;
}
crate::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?,
super::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?,
}
ControlFlow::Continue(())
}

View file

@ -4,5 +4,4 @@ version = "0.1.0-preview"
edition = "2024"
[dependencies]
scoped-tls = "1.0"
serde = { version = "1.0.125", features = [ "derive" ] }
rustc_smir = { path = "../rustc_smir" }

View file

@ -1,231 +1,7 @@
//! The WIP stable interface to rustc internals.
//! We've temporarily moved the `stable_mir` implementation to [`rustc_smir::stable_mir`],
//! during refactoring to break the circular dependency between `rustc_smir` and `stable_mir`,
//!
//! For more information see <https://github.com/rust-lang/project-stable-mir>
//!
//! # Note
//!
//! This API is still completely unstable and subject to change.
//! This is a transitional measure as described in [PR #139319](https://github.com/rust-lang/rust/pull/139319).
//! Once the refactoring is complete, the `stable_mir` implementation will be moved back here.
#![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).
use std::fmt::Debug;
use std::{fmt, io};
use serde::Serialize;
use crate::compiler_interface::with;
pub use crate::crate_def::{CrateDef, CrateDefItems, CrateDefType, DefId};
pub use crate::error::*;
use crate::mir::mono::StaticDef;
use crate::mir::{Body, Mutability};
use crate::ty::{AssocItem, FnDef, ForeignModuleDef, ImplDef, IndexedVal, Span, 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", &self.name()).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<CrateItem>;
/// A list of trait decls.
pub type TraitDecls = Vec<TraitDef>;
/// A list of impl trait decls.
pub type ImplTraitDecls = Vec<ImplDef>;
/// A list of associated items.
pub type AssocItems = Vec<AssocItem>;
/// Holds information about a crate.
#[derive(Clone, PartialEq, Eq, Debug, Serialize)]
pub struct Crate {
pub id: CrateNum,
pub name: Symbol,
pub is_local: bool,
}
impl Crate {
/// The list of foreign modules in this crate.
pub fn foreign_modules(&self) -> Vec<ForeignModuleDef> {
with(|cx| cx.foreign_modules(self.id))
}
/// The list of traits declared in this crate.
pub fn trait_decls(&self) -> TraitDecls {
with(|cx| cx.trait_decls(self.id))
}
/// The list of trait implementations in this crate.
pub fn trait_impls(&self) -> ImplTraitDecls {
with(|cx| cx.trait_impls(self.id))
}
/// Return a list of function definitions from this crate independent on their visibility.
pub fn fn_defs(&self) -> Vec<FnDef> {
with(|cx| cx.crate_functions(self.id))
}
/// Return a list of static items defined in this crate independent on their visibility.
pub fn statics(&self) -> Vec<StaticDef> {
with(|cx| cx.crate_statics(self.id))
}
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum ItemKind {
Fn,
Static,
Const,
Ctor(CtorKind),
}
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Serialize)]
pub enum CtorKind {
Const,
Fn,
}
pub type Filename = String;
crate_def_with_ty! {
/// Holds information about an item in a crate.
#[derive(Serialize)]
pub CrateItem;
}
impl CrateItem {
/// This will return the body of an item or panic if it's not available.
pub fn expect_body(&self) -> mir::Body {
with(|cx| cx.mir_body(self.0))
}
/// Return the body of an item if available.
pub fn body(&self) -> Option<mir::Body> {
with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
}
/// Check if a body is available for this item.
pub fn has_body(&self) -> bool {
with(|cx| cx.has_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))
}
/// Emit MIR for this item body.
pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
self.body()
.ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
.dump(w, &self.name())
}
}
/// 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<CrateItem> {
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<Crate> {
with(|cx| cx.find_crates(name))
}
/// Try to find a crate with the given name.
pub fn external_crates() -> Vec<Crate> {
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 all_trait_impls() -> ImplTraitDecls {
with(|cx| cx.all_trait_impls())
}
/// A type that provides internal information but that can still be used for debug purpose.
#[derive(Clone, PartialEq, Eq, Hash, Serialize)]
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<T: Debug>(value: &T) -> Opaque {
Opaque(format!("{value:?}"))
}
pub use rustc_smir::stable_mir::*;