Skip to content

Commit 368e454

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 608d6e8 commit 368e454

File tree

8 files changed

+417
-43
lines changed

8 files changed

+417
-43
lines changed

compiler/rustc_smir/src/rustc_smir/builder.rs

+14
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

+143-21
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;
1211
use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, 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,10 @@ 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, FloatTy, FnDef,
24+
GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy,
2525
};
26-
use stable_mir::{self, opaque, Context, Filename};
26+
use stable_mir::{self, opaque, Context, CrateItem, Filename, ItemKind};
2727
use std::cell::RefCell;
2828
use tracing::debug;
2929

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

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

93107
fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
@@ -198,10 +212,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
198212
}
199213
}
200214

201-
fn instance_body(&self, def: InstanceDef) -> Body {
215+
fn instance_body(&self, def: InstanceDef) -> Option<Body> {
202216
let mut tables = self.0.borrow_mut();
203217
let instance = tables.instances[def];
204-
builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables)
218+
tables
219+
.has_body(instance)
220+
.then(|| builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables))
205221
}
206222

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

254306
pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
@@ -271,6 +323,16 @@ impl<'tcx> Tables<'tcx> {
271323
fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId {
272324
self.constants.create_or_fetch(constant)
273325
}
326+
327+
fn has_body(&self, instance: Instance<'tcx>) -> bool {
328+
let def_id = instance.def_id();
329+
!self.tcx.is_foreign_item(def_id)
330+
&& self.tcx.is_mir_available(def_id)
331+
&& !matches!(
332+
instance.def,
333+
ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(..)
334+
)
335+
}
274336
}
275337

276338
/// Build a stable mir crate from a given crate number.
@@ -281,6 +343,43 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
281343
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
282344
}
283345

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

994+
impl<'tcx> Stable<'tcx> for ty::AdtKind {
995+
type T = AdtKind;
996+
997+
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
998+
match self {
999+
ty::AdtKind::Struct => AdtKind::Struct,
1000+
ty::AdtKind::Union => AdtKind::Union,
1001+
ty::AdtKind::Enum => AdtKind::Enum,
1002+
}
1003+
}
1004+
}
1005+
8951006
impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
8961007
type T = stable_mir::mir::CoroutineSource;
8971008
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@@ -1028,8 +1139,6 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
10281139
impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> {
10291140
type T = stable_mir::ty::GenericArgs;
10301141
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1031-
use stable_mir::ty::GenericArgs;
1032-
10331142
GenericArgs(self.iter().map(|arg| arg.unpack().stable(tables)).collect())
10341143
}
10351144
}
@@ -1293,7 +1402,7 @@ impl<'tcx> Stable<'tcx> for ty::TyKind<'tcx> {
12931402
TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables))
12941403
}
12951404
ty::Placeholder(..) | ty::CoroutineWitness(..) | ty::Infer(_) | ty::Error(_) => {
1296-
unreachable!();
1405+
unreachable!("Unexpected ty: {self:?}");
12971406
}
12981407
}
12991408
}
@@ -1448,7 +1557,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
14481557
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
14491558
use stable_mir::ty::TraitRef;
14501559

1451-
TraitRef { def_id: tables.trait_def(self.def_id), args: self.args.stable(tables) }
1560+
TraitRef::try_new(tables.trait_def(self.def_id), self.args.stable(tables)).unwrap()
14521561
}
14531562
}
14541563

@@ -1724,15 +1833,6 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
17241833
}
17251834
}
17261835

1727-
impl<'tcx> Stable<'tcx> for DefKind {
1728-
type T = stable_mir::DefKind;
1729-
1730-
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
1731-
// FIXME: add a real implementation of stable DefKind
1732-
opaque(self)
1733-
}
1734-
}
1735-
17361836
impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
17371837
type T = stable_mir::mir::mono::Instance;
17381838

@@ -1767,3 +1867,25 @@ impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
17671867
}
17681868
}
17691869
}
1870+
1871+
impl<'tcx, T> Stable<'tcx> for &T
1872+
where
1873+
T: Stable<'tcx>,
1874+
{
1875+
type T = T::T;
1876+
1877+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1878+
(*self).stable(tables)
1879+
}
1880+
}
1881+
1882+
impl<'tcx, T> Stable<'tcx> for Option<T>
1883+
where
1884+
T: Stable<'tcx>,
1885+
{
1886+
type T = Option<T::T>;
1887+
1888+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
1889+
self.as_ref().map(|value| value.stable(tables))
1890+
}
1891+
}

compiler/stable_mir/src/lib.rs

+36-5
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)