Skip to content

Commit a678833

Browse files
committed
Add MonoItems and Instance to stable_mir
Also add a few methods to instantiate instances and get an instance definition. We're still missing support to actually monomorphize the instance body.
1 parent 130ff8c commit a678833

File tree

8 files changed

+402
-45
lines changed

8 files changed

+402
-45
lines changed

compiler/rustc_smir/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#![cfg_attr(not(bootstrap), doc(rust_logo))]
1414
#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
1515
#![cfg_attr(not(bootstrap), allow(internal_features))]
16+
#![feature(map_try_insert)]
1617

1718
pub mod rustc_internal;
1819

compiler/rustc_smir/src/rustc_internal/mod.rs

+24-4
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
use crate::rustc_internal;
77
use crate::rustc_smir::Tables;
88
use rustc_data_structures::fx;
9+
use rustc_data_structures::fx::FxIndexMap;
910
use rustc_driver::{Callbacks, Compilation, RunCompiler};
1011
use rustc_interface::{interface, Queries};
1112
use rustc_middle::mir::interpret::AllocId;
13+
use rustc_middle::ty;
1214
use rustc_middle::ty::TyCtxt;
1315
use rustc_span::def_id::{CrateNum, DefId};
1416
use rustc_span::Span;
@@ -97,7 +99,7 @@ impl<'tcx> Tables<'tcx> {
9799
stable_mir::ty::Prov(self.create_alloc_id(aid))
98100
}
99101

100-
fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
102+
pub(crate) fn create_def_id(&mut self, did: DefId) -> stable_mir::DefId {
101103
self.def_ids.create_or_fetch(did)
102104
}
103105

@@ -108,6 +110,17 @@ impl<'tcx> Tables<'tcx> {
108110
pub(crate) fn create_span(&mut self, span: Span) -> stable_mir::ty::Span {
109111
self.spans.create_or_fetch(span)
110112
}
113+
114+
pub(crate) fn instance_def(
115+
&mut self,
116+
instance: ty::Instance<'tcx>,
117+
) -> stable_mir::mir::mono::InstanceDef {
118+
self.instances.create_or_fetch(instance)
119+
}
120+
121+
pub(crate) fn static_def(&mut self, did: DefId) -> stable_mir::mir::mono::StaticDef {
122+
stable_mir::mir::mono::StaticDef(self.create_def_id(did))
123+
}
111124
}
112125

113126
pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
@@ -118,10 +131,11 @@ pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
118131
stable_mir::run(
119132
Tables {
120133
tcx,
121-
def_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() },
122-
alloc_ids: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() },
123-
spans: rustc_internal::IndexMap { index_map: fx::FxIndexMap::default() },
134+
def_ids: IndexMap::default(),
135+
alloc_ids: IndexMap::default(),
136+
spans: IndexMap::default(),
124137
types: vec![],
138+
instances: IndexMap::default(),
125139
},
126140
f,
127141
);
@@ -192,6 +206,12 @@ pub struct IndexMap<K, V> {
192206
index_map: fx::FxIndexMap<K, V>,
193207
}
194208

209+
impl<K, V> Default for IndexMap<K, V> {
210+
fn default() -> Self {
211+
Self { index_map: FxIndexMap::default() }
212+
}
213+
}
214+
195215
impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> IndexMap<K, V> {
196216
pub fn create_or_fetch(&mut self, key: K) -> V {
197217
let len = self.index_map.len();

compiler/rustc_smir/src/rustc_smir/mod.rs

+99-26
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
1313
use rustc_hir as hir;
1414
use rustc_middle::mir;
1515
use rustc_middle::mir::interpret::{alloc_range, AllocId};
16-
use rustc_middle::ty::{self, Ty, TyCtxt, Variance};
16+
use rustc_middle::mir::mono::MonoItem;
17+
use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt, Variance};
1718
use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
1819
use rustc_target::abi::FieldIdx;
19-
use stable_mir::mir::{CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
20+
use stable_mir::mir::mono::InstanceDef;
21+
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
2022
use stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy};
2123
use stable_mir::{self, opaque, Context};
2224
use tracing::debug;
@@ -100,29 +102,7 @@ impl<'tcx> Context for Tables<'tcx> {
100102

101103
fn mir_body(&mut self, item: stable_mir::DefId) -> stable_mir::mir::Body {
102104
let def_id = self[item];
103-
let mir = self.tcx.instance_mir(ty::InstanceDef::Item(def_id));
104-
stable_mir::mir::Body {
105-
blocks: mir
106-
.basic_blocks
107-
.iter()
108-
.map(|block| stable_mir::mir::BasicBlock {
109-
terminator: block.terminator().stable(self),
110-
statements: block
111-
.statements
112-
.iter()
113-
.map(|statement| statement.stable(self))
114-
.collect(),
115-
})
116-
.collect(),
117-
locals: mir
118-
.local_decls
119-
.iter()
120-
.map(|decl| stable_mir::mir::LocalDecl {
121-
ty: self.intern_ty(decl.ty),
122-
span: decl.source_info.span.stable(self),
123-
})
124-
.collect(),
125-
}
105+
self.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(self)
126106
}
127107

128108
fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind {
@@ -171,6 +151,34 @@ impl<'tcx> Context for Tables<'tcx> {
171151
.collect(),
172152
}
173153
}
154+
155+
fn instance_body(&mut self, _def: InstanceDef) -> Body {
156+
todo!("Monomorphize the body")
157+
}
158+
159+
fn instance_ty(&mut self, def: InstanceDef) -> stable_mir::ty::Ty {
160+
let instance = self.instances[def];
161+
let ty = instance.ty(self.tcx, ParamEnv::empty());
162+
self.intern_ty(ty)
163+
}
164+
165+
fn instance_def_id(&mut self, def: InstanceDef) -> stable_mir::DefId {
166+
let def_id = self.instances[def].def_id();
167+
self.create_def_id(def_id)
168+
}
169+
170+
fn mono_instance(&mut self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
171+
let def_id = self[item.0];
172+
Instance::mono(self.tcx, def_id).stable(self)
173+
}
174+
175+
fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool {
176+
let def_id = self[def_id];
177+
let generics = self.tcx.generics_of(def_id);
178+
let result = generics.requires_monomorphization(self.tcx);
179+
println!("req {result}: {def_id:?}");
180+
result
181+
}
174182
}
175183

176184
#[derive(Clone)]
@@ -205,7 +213,8 @@ pub struct Tables<'tcx> {
205213
pub def_ids: IndexMap<DefId, stable_mir::DefId>,
206214
pub alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
207215
pub spans: IndexMap<rustc_span::Span, Span>,
208-
pub types: Vec<MaybeStable<stable_mir::ty::TyKind, Ty<'tcx>>>,
216+
pub types: Vec<MaybeStable<TyKind, Ty<'tcx>>>,
217+
pub instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
209218
}
210219

211220
impl<'tcx> Tables<'tcx> {
@@ -235,6 +244,35 @@ pub(crate) trait Stable<'tcx> {
235244
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T;
236245
}
237246

247+
impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
248+
type T = stable_mir::mir::Body;
249+
250+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
251+
stable_mir::mir::Body {
252+
blocks: self
253+
.basic_blocks
254+
.iter()
255+
.map(|block| stable_mir::mir::BasicBlock {
256+
terminator: block.terminator().stable(tables),
257+
statements: block
258+
.statements
259+
.iter()
260+
.map(|statement| statement.stable(tables))
261+
.collect(),
262+
})
263+
.collect(),
264+
locals: self
265+
.local_decls
266+
.iter()
267+
.map(|decl| stable_mir::mir::LocalDecl {
268+
ty: tables.intern_ty(decl.ty),
269+
span: decl.source_info.span.stable(tables),
270+
})
271+
.collect(),
272+
}
273+
}
274+
}
275+
238276
impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> {
239277
type T = stable_mir::mir::Statement;
240278
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
@@ -1618,3 +1656,38 @@ impl<'tcx> Stable<'tcx> for DefKind {
16181656
opaque(self)
16191657
}
16201658
}
1659+
1660+
impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
1661+
type T = stable_mir::mir::mono::Instance;
1662+
1663+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1664+
let def = tables.instance_def(*self);
1665+
let kind = match self.def {
1666+
ty::InstanceDef::Item(..) => stable_mir::mir::mono::InstanceKind::Item,
1667+
ty::InstanceDef::Intrinsic(..) => stable_mir::mir::mono::InstanceKind::Intrinsic,
1668+
ty::InstanceDef::Virtual(..) => stable_mir::mir::mono::InstanceKind::Virtual,
1669+
ty::InstanceDef::VTableShim(..)
1670+
| ty::InstanceDef::ReifyShim(..)
1671+
| ty::InstanceDef::FnPtrAddrShim(..)
1672+
| ty::InstanceDef::ClosureOnceShim { .. }
1673+
| ty::InstanceDef::ThreadLocalShim(..)
1674+
| ty::InstanceDef::DropGlue(..)
1675+
| ty::InstanceDef::CloneShim(..)
1676+
| ty::InstanceDef::FnPtrShim(..) => stable_mir::mir::mono::InstanceKind::Shim,
1677+
};
1678+
stable_mir::mir::mono::Instance { def, kind }
1679+
}
1680+
}
1681+
1682+
impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
1683+
type T = stable_mir::mir::mono::MonoItem;
1684+
1685+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1686+
use stable_mir::mir::mono::MonoItem as StableMonoItem;
1687+
match self {
1688+
MonoItem::Fn(instance) => StableMonoItem::Fn(instance.stable(tables)),
1689+
MonoItem::Static(def_id) => StableMonoItem::Static(tables.static_def(*def_id)),
1690+
MonoItem::GlobalAsm(item_id) => StableMonoItem::GlobalAsm(opaque(item_id)),
1691+
}
1692+
}
1693+
}

compiler/stable_mir/src/error.rs

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! When things go wrong, we need some error handling.
2+
//! There are a few different types of errors in StableMIR:
3+
//!
4+
//! - [CompilerError]: This represents errors that can be raised when invoking the compiler.
5+
//! - [Error]: Generic error that represents the reason why a request that could not be fulfilled.
6+
7+
use std::fmt::{Debug, Display, Formatter};
8+
use std::{error, fmt};
9+
10+
/// An error type used to represent an error that has already been reported by the compiler.
11+
#[derive(Clone, Copy, PartialEq, Eq)]
12+
pub enum CompilerError<T> {
13+
/// Internal compiler error (I.e.: Compiler crashed).
14+
ICE,
15+
/// Compilation failed.
16+
CompilationFailed,
17+
/// Compilation was interrupted.
18+
Interrupted(T),
19+
/// Compilation skipped. This happens when users invoke rustc to retrieve information such as
20+
/// --version.
21+
Skipped,
22+
}
23+
24+
/// A generic error to represent an API request that cannot be fulfilled.
25+
#[derive(Debug)]
26+
pub struct Error(String);
27+
28+
impl Error {
29+
pub(crate) fn new(msg: String) -> Self {
30+
Self(msg)
31+
}
32+
}
33+
34+
impl Display for Error {
35+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
36+
Display::fmt(&self.0, f)
37+
}
38+
}
39+
40+
impl<T> Display for CompilerError<T>
41+
where
42+
T: Display,
43+
{
44+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
45+
match self {
46+
CompilerError::ICE => write!(f, "Internal Compiler Error"),
47+
CompilerError::CompilationFailed => write!(f, "Compilation Failed"),
48+
CompilerError::Interrupted(reason) => write!(f, "Compilation Interrupted: {reason}"),
49+
CompilerError::Skipped => write!(f, "Compilation Skipped"),
50+
}
51+
}
52+
}
53+
54+
impl<T> Debug for CompilerError<T>
55+
where
56+
T: Debug,
57+
{
58+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
59+
match self {
60+
CompilerError::ICE => write!(f, "Internal Compiler Error"),
61+
CompilerError::CompilationFailed => write!(f, "Compilation Failed"),
62+
CompilerError::Interrupted(reason) => write!(f, "Compilation Interrupted: {reason:?}"),
63+
CompilerError::Skipped => write!(f, "Compilation Skipped"),
64+
}
65+
}
66+
}
67+
68+
impl error::Error for Error {}
69+
impl<T> error::Error for CompilerError<T> where T: Display + Debug {}

0 commit comments

Comments
 (0)