1
Fork 0

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.
This commit is contained in:
Celina G. Val 2023-11-16 12:01:10 -08:00
parent 3f87dac9a2
commit 6515ac9d3f
9 changed files with 422 additions and 47 deletions

View file

@ -49,6 +49,20 @@ impl<'tcx> MutVisitor<'tcx> for BodyBuilder<'tcx> {
*ty = self.monomorphize(*ty);
}
fn visit_constant(&mut self, constant: &mut mir::ConstOperand<'tcx>, location: mir::Location) {
let const_ = self.monomorphize(constant.const_);
let val = match const_.eval(self.tcx, ty::ParamEnv::reveal_all(), None) {
Ok(v) => v,
Err(mir::interpret::ErrorHandled::Reported(..)) => return,
Err(mir::interpret::ErrorHandled::TooGeneric(..)) => {
unreachable!("Failed to evaluate instance constant: {:?}", const_)
}
};
let ty = constant.ty();
constant.const_ = mir::Const::Val(val, ty);
self.super_constant(constant, location);
}
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}

View file

@ -8,9 +8,9 @@
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
use crate::rustc_internal::{IndexMap, RustcInternal};
use crate::rustc_smir::hir::def::DefKind;
use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyParamRegion, Region};
use crate::rustc_smir::stable_mir::ty::{BoundRegion, Region};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_middle::mir;
use rustc_middle::mir::interpret::{alloc_range, AllocId};
use rustc_middle::mir::mono::MonoItem;
@ -20,10 +20,11 @@ use rustc_target::abi::FieldIdx;
use stable_mir::mir::mono::InstanceDef;
use stable_mir::mir::{Body, CopyNonOverlapping, Statement, UserTypeProjection, VariantIdx};
use stable_mir::ty::{
Const, ConstId, ConstantKind, FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy,
Span, TyKind, UintTy,
AdtDef, AdtKind, ClosureDef, ClosureKind, Const, ConstId, ConstantKind, EarlyParamRegion,
FloatTy, FnDef, GenericArgs, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span,
TyKind, UintTy,
};
use stable_mir::{self, opaque, Context, Filename};
use stable_mir::{self, opaque, Context, CrateItem, Filename, ItemKind};
use std::cell::RefCell;
use tracing::debug;
@ -85,9 +86,23 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
}
fn def_kind(&self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
fn item_kind(&self, item: CrateItem) -> ItemKind {
let tables = self.0.borrow();
new_item_kind(tables.tcx.def_kind(tables[item.0]))
}
fn adt_kind(&self, def: AdtDef) -> AdtKind {
let mut tables = self.0.borrow_mut();
tables.tcx.def_kind(tables[def_id]).stable(&mut *tables)
let ty = tables.tcx.type_of(def.0.internal(&mut *tables)).instantiate_identity().kind();
let ty::TyKind::Adt(def, _) = ty else {
panic!("Expected an ADT definition, but found: {ty:?}")
};
def.adt_kind().stable(&mut *tables)
}
fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty {
let mut tables = self.0.borrow_mut();
tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables)
}
fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
@ -198,10 +213,12 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
}
}
fn instance_body(&self, def: InstanceDef) -> Body {
fn instance_body(&self, def: InstanceDef) -> Option<Body> {
let mut tables = self.0.borrow_mut();
let instance = tables.instances[def];
builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables)
tables
.has_body(instance)
.then(|| builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables))
}
fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
@ -249,6 +266,42 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
Ok(None) | Err(_) => None,
}
}
fn resolve_drop_in_place(
&self,
ty: stable_mir::ty::Ty,
) -> Option<stable_mir::mir::mono::Instance> {
let mut tables = self.0.borrow_mut();
let internal_ty = ty.internal(&mut *tables);
let instance = Instance::resolve_drop_in_place(tables.tcx, internal_ty);
matches!(instance.def, ty::InstanceDef::DropGlue(_, Some(_)))
.then(|| instance.stable(&mut *tables))
}
fn resolve_for_fn_ptr(
&self,
def: FnDef,
args: &GenericArgs,
) -> Option<stable_mir::mir::mono::Instance> {
let mut tables = self.0.borrow_mut();
let def_id = def.0.internal(&mut *tables);
let args_ref = args.internal(&mut *tables);
Instance::resolve_for_fn_ptr(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref)
.stable(&mut *tables)
}
fn resolve_closure(
&self,
def: ClosureDef,
args: &GenericArgs,
kind: ClosureKind,
) -> Option<stable_mir::mir::mono::Instance> {
let mut tables = self.0.borrow_mut();
let def_id = def.0.internal(&mut *tables);
let args_ref = args.internal(&mut *tables);
let closure_kind = kind.internal(&mut *tables);
Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind).stable(&mut *tables)
}
}
pub(crate) struct TablesWrapper<'tcx>(pub(crate) RefCell<Tables<'tcx>>);
@ -271,6 +324,16 @@ impl<'tcx> Tables<'tcx> {
fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId {
self.constants.create_or_fetch(constant)
}
fn has_body(&self, instance: Instance<'tcx>) -> bool {
let def_id = instance.def_id();
!self.tcx.is_foreign_item(def_id)
&& self.tcx.is_mir_available(def_id)
&& !matches!(
instance.def,
ty::InstanceDef::Virtual(..) | ty::InstanceDef::Intrinsic(..)
)
}
}
/// 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 {
stable_mir::Crate { id: crate_num.into(), name: crate_name, is_local }
}
fn new_item_kind(kind: DefKind) -> ItemKind {
match kind {
DefKind::Mod
| DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::Variant
| DefKind::Trait
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::AssocTy
| DefKind::TyParam
| DefKind::ConstParam
| DefKind::Macro(_)
| DefKind::ExternCrate
| DefKind::Use
| DefKind::ForeignMod
| DefKind::OpaqueTy
| DefKind::Field
| DefKind::LifetimeParam
| DefKind::GlobalAsm => {
unreachable!("Not a valid item kind: {kind:?}");
}
DefKind::Closure
| DefKind::Coroutine
| DefKind::Ctor(_, _)
| DefKind::AssocFn
| DefKind::Impl { .. }
| DefKind::Fn => ItemKind::Fn,
DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => {
ItemKind::Const
}
DefKind::Static(_) => ItemKind::Static,
}
}
/// Trait used to convert between an internal MIR type to a Stable MIR type.
pub trait Stable<'tcx> {
/// The stable representation of the type implementing Stable.
@ -926,6 +1026,18 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
}
}
impl<'tcx> Stable<'tcx> for ty::AdtKind {
type T = AdtKind;
fn stable(&self, _tables: &mut Tables<'tcx>) -> Self::T {
match self {
ty::AdtKind::Struct => AdtKind::Struct,
ty::AdtKind::Union => AdtKind::Union,
ty::AdtKind::Enum => AdtKind::Enum,
}
}
}
impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
type T = stable_mir::mir::CoroutineSource;
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
@ -1062,8 +1174,6 @@ impl<'tcx> Stable<'tcx> for mir::TerminatorKind<'tcx> {
impl<'tcx> Stable<'tcx> for ty::GenericArgs<'tcx> {
type T = stable_mir::ty::GenericArgs;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
use stable_mir::ty::GenericArgs;
GenericArgs(self.iter().map(|arg| arg.unpack().stable(tables)).collect())
}
}
@ -1486,7 +1596,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: tables.trait_def(self.def_id), args: self.args.stable(tables) }
TraitRef::try_new(tables.trait_def(self.def_id), self.args.stable(tables)).unwrap()
}
}
@ -1762,15 +1872,6 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
}
}
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)
}
}
impl<'tcx> Stable<'tcx> for ty::Instance<'tcx> {
type T = stable_mir::mir::mono::Instance;
@ -1805,3 +1906,25 @@ impl<'tcx> Stable<'tcx> for MonoItem<'tcx> {
}
}
}
impl<'tcx, T> Stable<'tcx> for &T
where
T: Stable<'tcx>,
{
type T = T::T;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
(*self).stable(tables)
}
}
impl<'tcx, T> Stable<'tcx> for Option<T>
where
T: Stable<'tcx>,
{
type T = Option<T::T>;
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
self.as_ref().map(|value| value.stable(tables))
}
}