Skip to content

Commit 6515ac9

Browse files
committed
Add more APIs and fix Instance::body
Add more APIs to retrieve information about types, and add more instance resolution options. Make `Instance::body()` return an Option<Body>, since not every instance might have an available body. For example, foreign instances, virtual instances, dependencies.
1 parent 3f87dac commit 6515ac9

File tree

9 files changed

+422
-47
lines changed

9 files changed

+422
-47
lines changed

compiler/rustc_smir/src/rustc_smir/builder.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
4949
*ty = self.monomorphize(*ty);
5050
}
5151

52+
fn visit_constant(&mut self, constant: &mut mir::ConstOperand<'tcx>, location: mir::Location) {
53+
let const_ = self.monomorphize(constant.const_);
54+
let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), None) {
55+
Ok(v) => v,
56+
Err(mir::interpret::ErrorHandled::Reported(..)) => return,
57+
Err(mir::interpret::ErrorHandled::TooGeneric(..)) => {
58+
unreachable!("Failed to evaluate instance constant: {:?}", const_)
59+
}
60+
};
61+
let ty = constant.ty();
62+
constant.const_ = mir::Const::Val(val, ty);
63+
self.super_constant(constant, location);
64+
}
65+
5266
fn tcx(&self) -> TyCtxt<'tcx> {
5367
self.tcx
5468
}

compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 144 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
99
1010
use crate::rustc_internal::{IndexMap, RustcInternal};
11-
use crate::rustc_smir::hir::def::DefKind;
12-
use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyParamRegion, Region};
11+
use crate::rustc_smir::stable_mir::ty::{BoundRegion, Region};
1312
use rustc_hir as hir;
13+
use rustc_hir::def::DefKind;
1414
use rustc_middle::mir;
1515
use rustc_middle::mir::interpret::{alloc_range, AllocId};
1616
use rustc_middle::mir::mono::MonoItem;
@@ -20,10 +20,11 @@ use rustc_target::abi::FieldIdx;
2020
use stable_mir::mir::mono::InstanceDef;
2121
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
2222
use stable_mir::ty::{
23-
Const, ConstId, ConstantKind, FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy,
24-
Span, TyKind, UintTy,
23+
AdtDef, AdtKind, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, EarlyParamRegion,
24+
FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span,
25+
TyKind, UintTy,
2526
};
26-
use stable_mir::{self, opaque, Context, Filename};
27+
use stable_mir::{self, opaque, Context, CrateItem, Filename, ItemKind};
2728
use std::cell::RefCell;
2829
use tracing::debug;
2930

@@ -85,9 +86,23 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
8586
LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
8687
}
8788

88-
fn def_kind(&self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
89+
fn item_kind(&self, item: CrateItem) -> ItemKind {
90+
let tables = self.0.borrow();
91+
new_item_kind(tables.tcx.def_kind(tables[item.0]))
92+
}
93+
94+
fn adt_kind(&self, def: AdtDef) -> AdtKind {
95+
let mut tables = self.0.borrow_mut();
96+
let ty = tables.tcx.type_of(def.0.internal(&mut *tables)).instantiate_identity().kind();
97+
let ty::TyKind::Adt(def, _) = ty else {
98+
panic!("Expected an ADT definition, but found: {ty:?}")
99+
};
100+
def.adt_kind().stable(&mut *tables)
101+
}
102+
103+
fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty {
89104
let mut tables = self.0.borrow_mut();
90-
tables.tcx.def_kind(tables[def_id]).stable(&mut *tables)
105+
tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables)
91106
}
92107

93108
fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
@@ -198,10 +213,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
198213
}
199214
}
200215

201-
fn instance_body(&self, def: InstanceDef) -> Body {
216+
fn instance_body(&self, def: InstanceDef) -> Option<Body> {
202217
let mut tables = self.0.borrow_mut();
203218
let instance = tables.instances[def];
204-
builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables)
219+
tables
220+
.has_body(instance)
221+
.then(|| builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables))
205222
}
206223

207224
fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
@@ -249,6 +266,42 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
249266
Ok(None) | Err(_) => None,
250267
}
251268
}
269+
270+
fn resolve_drop_in_place(
271+
&self,
272+
ty: stable_mir::ty::Ty,
273+
) -> Option<stable_mir::mir::mono::Instance> {
274+
let mut tables = self.0.borrow_mut();
275+
let internal_ty = ty.internal(&mut *tables);
276+
let instance = Instance::resolve_drop_in_place(tables.tcx, internal_ty);
277+
matches!(instance.def, ty::InstanceDef::DropGlue(_, Some(_)))
278+
.then(|| instance.stable(&mut *tables))
279+
}
280+
281+
fn resolve_for_fn_ptr(
282+
&self,
283+
def: FnDef,
284+
args: &GenericArgs,
285+
) -> Option<stable_mir::mir::mono::Instance> {
286+
let mut tables = self.0.borrow_mut();
287+
let def_id = def.0.internal(&mut *tables);
288+
let args_ref = args.internal(&mut *tables);
289+
Instance::resolve_for_fn_ptr(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref)
290+
.stable(&mut *tables)
291+
}
292+
293+
fn resolve_closure(
294+
&self,
295+
def: ClosureDef,
296+
args: &GenericArgs,
297+
kind: ClosureKind,
298+
) -> Option<stable_mir::mir::mono::Instance> {
299+
let mut tables = self.0.borrow_mut();
300+
let def_id = def.0.internal(&mut *tables);
301+
let args_ref = args.internal(&mut *tables);
302+
let closure_kind = kind.internal(&mut *tables);
303+
Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind).stable(&mut *tables)
304+
}
252305
}
253306

254307
pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
@@ -271,6 +324,16 @@ impl<'tcx> Tables<'tcx> {
271324
fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId {
272325
self.constants.create_or_fetch(constant)
273326
}
327+
328+
fn has_body(&self, instance: Instance<'tcx>) -> bool {
329+
let def_id = instance.def_id();
330+
!self.tcx.is_foreign_item(def_id)
331+
&& self.tcx.is_mir_available(def_id)
332+
&& !matches!(
333+
instance.def,
334+
ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(..)
335+
)
336+
}
274337
}
275338

276339
/// Build a stable mir crate from a given crate number.
@@ -281,6 +344,43 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
281344
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
282345
}
283346

347+
fn new_item_kind(kind: DefKind) -> ItemKind {
348+
match kind {
349+
DefKind::Mod
350+
| DefKind::Struct
351+
| DefKind::Union
352+
| DefKind::Enum
353+
| DefKind::Variant
354+
| DefKind::Trait
355+
| DefKind::TyAlias
356+
| DefKind::ForeignTy
357+
| DefKind::TraitAlias
358+
| DefKind::AssocTy
359+
| DefKind::TyParam
360+
| DefKind::ConstParam
361+
| DefKind::Macro(_)
362+
| DefKind::ExternCrate
363+
| DefKind::Use
364+
| DefKind::ForeignMod
365+
| DefKind::OpaqueTy
366+
| DefKind::Field
367+
| DefKind::LifetimeParam
368+
| DefKind::GlobalAsm => {
369+
unreachable!("Not a valid item kind: {kind:?}");
370+
}
371+
DefKind::Closure
372+
| DefKind::Coroutine
373+
| DefKind::Ctor(_, _)
374+
| DefKind::AssocFn
375+
| DefKind::Impl { .. }
376+
| DefKind::Fn => ItemKind::Fn,
377+
DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => {
378+
ItemKind::Const
379+
}
380+
DefKind::Static(_) => ItemKind::Static,
381+
}
382+
}
383+
284384
/// Trait used to convert between an internal MIR type to a Stable MIR type.
285385
pub trait Stable<'tcx> {
286386
/// The stable representation of the type implementing Stable.
@@ -926,6 +1026,18 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
9261026
}
9271027
}
9281028

1029+
impl<'tcx> Stable<'tcx> for ty::AdtKind {
1030+
type T = AdtKind;
1031+
1032+
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
1033+
match self {
1034+
ty::AdtKind::Struct => AdtKind::Struct,
1035+
ty::AdtKind::Union => AdtKind::Union,
1036+
ty::AdtKind::Enum => AdtKind::Enum,
1037+
}
1038+
}
1039+
}
1040+
9291041
impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
9301042
type T = stable_mir::mir::CoroutineSource;
9311043
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@@ -1062,8 +1174,6 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
10621174
impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> {
10631175
type T = stable_mir::ty::GenericArgs;
10641176
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1065-
use stable_mir::ty::GenericArgs;
1066-
10671177
GenericArgs(self.iter().map(|arg| arg.unpack().stable(tables)).collect())
10681178
}
10691179
}
@@ -1486,7 +1596,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
14861596
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
14871597
use stable_mir::ty::TraitRef;
14881598

1489-
TraitRef { def_id: tables.trait_def(self.def_id), args: self.args.stable(tables) }
1599+
TraitRef::try_new(tables.trait_def(self.def_id), self.args.stable(tables)).unwrap()
14901600
}
14911601
}
14921602

@@ -1762,15 +1872,6 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
17621872
}
17631873
}
17641874

1765-
impl<'tcx> Stable<'tcx> for DefKind {
1766-
type T = stable_mir::DefKind;
1767-
1768-
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
1769-
// FIXME: add a real implementation of stable DefKind
1770-
opaque(self)
1771-
}
1772-
}
1773-
17741875
impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
17751876
type T = stable_mir::mir::mono::Instance;
17761877

@@ -1805,3 +1906,25 @@ impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
18051906
}
18061907
}
18071908
}
1909+
1910+
impl<'tcx, T> Stable<'tcx> for &T
1911+
where
1912+
T: Stable<'tcx>,
1913+
{
1914+
type T = T::T;
1915+
1916+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1917+
(*self).stable(tables)
1918+
}
1919+
}
1920+
1921+
impl<'tcx, T> Stable<'tcx> for Option<T>
1922+
where
1923+
T: Stable<'tcx>,
1924+
{
1925+
type T = Option<T::T>;
1926+
1927+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1928+
self.as_ref().map(|value| value.stable(tables))
1929+
}
1930+
}

compiler/stable_mir/src/lib.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub mod mir;
3636
pub mod ty;
3737
pub mod visitor;
3838

39+
use crate::ty::{AdtDef, AdtKind, ClosureDef, ClosureKind};
3940
pub use error::*;
4041
use mir::mono::Instance;
4142
use ty::{FnDef, GenericArgs};
@@ -99,7 +100,13 @@ pub struct Crate {
99100
pub is_local: bool,
100101
}
101102

102-
pub type DefKind = Opaque;
103+
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
104+
pub enum ItemKind {
105+
Fn,
106+
Static,
107+
Const,
108+
}
109+
103110
pub type Filename = Opaque;
104111

105112
/// Holds information about an item in the crate.
@@ -119,13 +126,17 @@ impl CrateItem {
119126
with(|cx| cx.name_of_def_id(self.0))
120127
}
121128

122-
pub fn kind(&self) -> DefKind {
123-
with(|cx| cx.def_kind(self.0))
129+
pub fn kind(&self) -> ItemKind {
130+
with(|cx| cx.item_kind(*self))
124131
}
125132

126133
pub fn requires_monomorphization(&self) -> bool {
127134
with(|cx| cx.requires_monomorphization(self.0))
128135
}
136+
137+
pub fn ty(&self) -> Ty {
138+
with(|cx| cx.def_ty(self.0))
139+
}
129140
}
130141

131142
/// Return the function where execution starts if the current
@@ -204,7 +215,13 @@ pub trait Context {
204215
fn get_lines(&self, span: &Span) -> LineInfo;
205216

206217
/// Returns the `kind` of given `DefId`
207-
fn def_kind(&self, def_id: DefId) -> DefKind;
218+
fn item_kind(&self, item: CrateItem) -> ItemKind;
219+
220+
/// Returns the kind of a given algebraic data type
221+
fn adt_kind(&self, def: AdtDef) -> AdtKind;
222+
223+
/// Returns the type of given crate item.
224+
fn def_ty(&self, item: DefId) -> Ty;
208225

209226
/// `Span` of an item
210227
fn span_of_an_item(&self, def_id: DefId) -> Span;
@@ -214,7 +231,7 @@ pub trait Context {
214231

215232
/// Get the body of an Instance.
216233
/// FIXME: Monomorphize the body.
217-
fn instance_body(&self, instance: InstanceDef) -> Body;
234+
fn instance_body(&self, instance: InstanceDef) -> Option<Body>;
218235

219236
/// Get the instance type with generic substitutions applied and lifetimes erased.
220237
fn instance_ty(&self, instance: InstanceDef) -> Ty;
@@ -234,6 +251,20 @@ pub trait Context {
234251

235252
/// Resolve an instance from the given function definition and generic arguments.
236253
fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
254+
255+
/// Resolve an instance for drop_in_place for the given type.
256+
fn resolve_drop_in_place(&self, ty: Ty) -> Option<Instance>;
257+
258+
/// Resolve instance for a function pointer.
259+
fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
260+
261+
/// Resolve instance for a closure with the requested type.
262+
fn resolve_closure(
263+
&self,
264+
def: ClosureDef,
265+
args: &GenericArgs,
266+
kind: ClosureKind,
267+
) -> Option<Instance>;
237268
}
238269

239270
// A thread local variable that stores a pointer to the tables mapping between TyCtxt

0 commit comments

Comments
 (0)