Add method to convert internal to stable constructs
This commit is contained in:
parent
e2068cdb09
commit
66a554b045
5 changed files with 197 additions and 121 deletions
|
@ -4524,6 +4524,7 @@ dependencies = [
|
||||||
"rustc_middle",
|
"rustc_middle",
|
||||||
"rustc_span",
|
"rustc_span",
|
||||||
"rustc_target",
|
"rustc_target",
|
||||||
|
"scoped-tls",
|
||||||
"stable_mir",
|
"stable_mir",
|
||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
|
@ -9,6 +9,7 @@ rustc_hir = { path = "../rustc_hir" }
|
||||||
rustc_middle = { path = "../rustc_middle" }
|
rustc_middle = { path = "../rustc_middle" }
|
||||||
rustc_span = { path = "../rustc_span" }
|
rustc_span = { path = "../rustc_span" }
|
||||||
rustc_target = { path = "../rustc_target" }
|
rustc_target = { path = "../rustc_target" }
|
||||||
|
scoped-tls = "1.0"
|
||||||
stable_mir = {path = "../stable_mir" }
|
stable_mir = {path = "../stable_mir" }
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
|
//! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
|
||||||
//! until stable MIR is complete.
|
//! until stable MIR is complete.
|
||||||
|
|
||||||
use crate::rustc_smir::Tables;
|
use crate::rustc_smir::{Stable, Tables, TablesWrapper};
|
||||||
use rustc_data_structures::fx;
|
use rustc_data_structures::fx;
|
||||||
use rustc_data_structures::fx::FxIndexMap;
|
use rustc_data_structures::fx::FxIndexMap;
|
||||||
use rustc_middle::mir::interpret::AllocId;
|
use rustc_middle::mir::interpret::AllocId;
|
||||||
|
@ -11,13 +11,21 @@ use rustc_middle::ty;
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
use rustc_span::def_id::{CrateNum, DefId};
|
use rustc_span::def_id::{CrateNum, DefId};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
|
use scoped_tls::scoped_thread_local;
|
||||||
use stable_mir::ty::IndexedVal;
|
use stable_mir::ty::IndexedVal;
|
||||||
|
use std::cell::Cell;
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
mod internal;
|
mod internal;
|
||||||
|
|
||||||
|
pub unsafe fn stable<'tcx, S: Stable<'tcx>>(item: &S) -> S::T {
|
||||||
|
with_tables(|tables| item.stable(tables))
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
|
impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
|
||||||
type Output = DefId;
|
type Output = DefId;
|
||||||
|
|
||||||
|
@ -125,18 +133,44 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
|
||||||
item.id.into()
|
item.id.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
|
||||||
|
// datastructures and stable MIR datastructures
|
||||||
|
scoped_thread_local! (static TLV: Cell<*const ()>);
|
||||||
|
|
||||||
|
pub(crate) fn init<'tcx>(tables: TablesWrapper<'tcx>, f: impl FnOnce()) {
|
||||||
|
assert!(!TLV.is_set());
|
||||||
|
fn g<'a, 'tcx>(context: &'a TablesWrapper<'tcx>, f: impl FnOnce()) {
|
||||||
|
let ptr: *const () = &context as *const &_ as _;
|
||||||
|
TLV.set(&Cell::new(ptr), || {
|
||||||
|
f();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
g(&tables, f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Loads the current context and calls a function with it.
|
||||||
|
/// Do not nest these, as that will ICE.
|
||||||
|
pub(crate) fn with_tables<'tcx, R>(f: impl FnOnce(&mut Tables<'tcx>) -> R) -> R {
|
||||||
|
assert!(TLV.is_set());
|
||||||
|
TLV.with(|tlv| {
|
||||||
|
let ptr = tlv.get();
|
||||||
|
assert!(!ptr.is_null());
|
||||||
|
let wrapper = unsafe { *(ptr as *const &TablesWrapper<'tcx>) };
|
||||||
|
let mut tables = wrapper.0.borrow_mut();
|
||||||
|
f(&mut *tables)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
|
pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
|
||||||
stable_mir::run(
|
let tables = Rc::new(RefCell::new(Tables {
|
||||||
Tables {
|
|
||||||
tcx,
|
tcx,
|
||||||
def_ids: IndexMap::default(),
|
def_ids: IndexMap::default(),
|
||||||
alloc_ids: IndexMap::default(),
|
alloc_ids: IndexMap::default(),
|
||||||
spans: IndexMap::default(),
|
spans: IndexMap::default(),
|
||||||
types: vec![],
|
types: vec![],
|
||||||
instances: IndexMap::default(),
|
instances: IndexMap::default(),
|
||||||
},
|
}));
|
||||||
f,
|
stable_mir::run(TablesWrapper(Rc::clone(&tables)), || init(TablesWrapper(tables), f));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|
|
@ -23,27 +23,31 @@ use stable_mir::ty::{
|
||||||
FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy,
|
FloatTy, GenericParamDef, IntTy, LineInfo, Movability, RigidTy, Span, TyKind, UintTy,
|
||||||
};
|
};
|
||||||
use stable_mir::{self, opaque, Context, Filename};
|
use stable_mir::{self, opaque, Context, Filename};
|
||||||
|
use std::cell::RefCell;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
mod alloc;
|
mod alloc;
|
||||||
mod builder;
|
mod builder;
|
||||||
|
|
||||||
impl<'tcx> Context for Tables<'tcx> {
|
impl<'tcx> Context for TablesWrapper<'tcx> {
|
||||||
fn local_crate(&self) -> stable_mir::Crate {
|
fn local_crate(&self) -> stable_mir::Crate {
|
||||||
smir_crate(self.tcx, LOCAL_CRATE)
|
let tables = self.0.borrow();
|
||||||
|
smir_crate(tables.tcx, LOCAL_CRATE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn external_crates(&self) -> Vec<stable_mir::Crate> {
|
fn external_crates(&self) -> Vec<stable_mir::Crate> {
|
||||||
self.tcx.crates(()).iter().map(|crate_num| smir_crate(self.tcx, *crate_num)).collect()
|
let tables = self.0.borrow();
|
||||||
|
tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> {
|
fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> {
|
||||||
|
let tables = self.0.borrow();
|
||||||
let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE]
|
let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE]
|
||||||
.iter()
|
.iter()
|
||||||
.chain(self.tcx.crates(()).iter())
|
.chain(tables.tcx.crates(()).iter())
|
||||||
.map(|crate_num| {
|
.map(|crate_num| {
|
||||||
let crate_name = self.tcx.crate_name(*crate_num).to_string();
|
let crate_name = tables.tcx.crate_name(*crate_num).to_string();
|
||||||
(name == crate_name).then(|| smir_crate(self.tcx, *crate_num))
|
(name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))
|
||||||
})
|
})
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|c| c)
|
.filter_map(|c| c)
|
||||||
|
@ -52,163 +56,197 @@ impl<'tcx> Context for Tables<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String {
|
fn name_of_def_id(&self, def_id: stable_mir::DefId) -> String {
|
||||||
self.tcx.def_path_str(self[def_id])
|
let tables = self.0.borrow();
|
||||||
|
tables.tcx.def_path_str(tables[def_id])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
|
fn span_to_string(&self, span: stable_mir::ty::Span) -> String {
|
||||||
self.tcx.sess.source_map().span_to_diagnostic_string(self[span])
|
let tables = self.0.borrow();
|
||||||
|
tables.tcx.sess.source_map().span_to_diagnostic_string(tables[span])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_filename(&self, span: &Span) -> Filename {
|
fn get_filename(&self, span: &Span) -> Filename {
|
||||||
|
let tables = self.0.borrow();
|
||||||
opaque(
|
opaque(
|
||||||
&self
|
&tables
|
||||||
.tcx
|
.tcx
|
||||||
.sess
|
.sess
|
||||||
.source_map()
|
.source_map()
|
||||||
.span_to_filename(self[*span])
|
.span_to_filename(tables[*span])
|
||||||
.display(rustc_span::FileNameDisplayPreference::Local)
|
.display(rustc_span::FileNameDisplayPreference::Local)
|
||||||
.to_string(),
|
.to_string(),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_lines(&self, span: &Span) -> LineInfo {
|
fn get_lines(&self, span: &Span) -> LineInfo {
|
||||||
let lines = &self.tcx.sess.source_map().span_to_location_info(self[*span]);
|
let tables = self.0.borrow();
|
||||||
|
let lines = &tables.tcx.sess.source_map().span_to_location_info(tables[*span]);
|
||||||
LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
|
LineInfo { start_line: lines.1, start_col: lines.2, end_line: lines.3, end_col: lines.4 }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
|
fn def_kind(&self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
|
||||||
self.tcx.def_kind(self[def_id]).stable(self)
|
let mut tables = self.0.borrow_mut();
|
||||||
|
tables.tcx.def_kind(tables[def_id]).stable(&mut *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> Span {
|
fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span {
|
||||||
self.tcx.def_span(self[def_id]).stable(self)
|
let mut tables = self.0.borrow_mut();
|
||||||
|
tables.tcx.def_span(tables[def_id]).stable(&mut *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_local_items(&mut self) -> stable_mir::CrateItems {
|
fn all_local_items(&self) -> stable_mir::CrateItems {
|
||||||
self.tcx.mir_keys(()).iter().map(|item| self.crate_item(item.to_def_id())).collect()
|
let mut tables = self.0.borrow_mut();
|
||||||
|
tables.tcx.mir_keys(()).iter().map(|item| tables.crate_item(item.to_def_id())).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn entry_fn(&mut self) -> Option<stable_mir::CrateItem> {
|
fn entry_fn(&self) -> Option<stable_mir::CrateItem> {
|
||||||
Some(self.crate_item(self.tcx.entry_fn(())?.0))
|
let mut tables = self.0.borrow_mut();
|
||||||
|
let tcx = tables.tcx;
|
||||||
|
Some(tables.crate_item(tcx.entry_fn(())?.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_trait_decls(&mut self) -> stable_mir::TraitDecls {
|
fn all_trait_decls(&self) -> stable_mir::TraitDecls {
|
||||||
self.tcx
|
let mut tables = self.0.borrow_mut();
|
||||||
|
tables
|
||||||
|
.tcx
|
||||||
.traits(LOCAL_CRATE)
|
.traits(LOCAL_CRATE)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|trait_def_id| self.trait_def(*trait_def_id))
|
.map(|trait_def_id| tables.trait_def(*trait_def_id))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trait_decl(&mut self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
|
fn trait_decl(&self, trait_def: &stable_mir::ty::TraitDef) -> stable_mir::ty::TraitDecl {
|
||||||
let def_id = self[trait_def.0];
|
let mut tables = self.0.borrow_mut();
|
||||||
let trait_def = self.tcx.trait_def(def_id);
|
let def_id = tables[trait_def.0];
|
||||||
trait_def.stable(self)
|
let trait_def = tables.tcx.trait_def(def_id);
|
||||||
|
trait_def.stable(&mut *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_trait_impls(&mut self) -> stable_mir::ImplTraitDecls {
|
fn all_trait_impls(&self) -> stable_mir::ImplTraitDecls {
|
||||||
self.tcx
|
let mut tables = self.0.borrow_mut();
|
||||||
|
tables
|
||||||
|
.tcx
|
||||||
.trait_impls_in_crate(LOCAL_CRATE)
|
.trait_impls_in_crate(LOCAL_CRATE)
|
||||||
.iter()
|
.iter()
|
||||||
.map(|impl_def_id| self.impl_def(*impl_def_id))
|
.map(|impl_def_id| tables.impl_def(*impl_def_id))
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trait_impl(&mut self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
|
fn trait_impl(&self, impl_def: &stable_mir::ty::ImplDef) -> stable_mir::ty::ImplTrait {
|
||||||
let def_id = self[impl_def.0];
|
let mut tables = self.0.borrow_mut();
|
||||||
let impl_trait = self.tcx.impl_trait_ref(def_id).unwrap();
|
let def_id = tables[impl_def.0];
|
||||||
impl_trait.stable(self)
|
let impl_trait = tables.tcx.impl_trait_ref(def_id).unwrap();
|
||||||
|
impl_trait.stable(&mut *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mir_body(&mut self, item: stable_mir::DefId) -> stable_mir::mir::Body {
|
fn mir_body(&self, item: stable_mir::DefId) -> stable_mir::mir::Body {
|
||||||
let def_id = self[item];
|
let mut tables = self.0.borrow_mut();
|
||||||
self.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(self)
|
let def_id = tables[item];
|
||||||
|
tables.tcx.instance_mir(ty::InstanceDef::Item(def_id)).stable(&mut tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind {
|
fn ty_kind(&self, ty: stable_mir::ty::Ty) -> TyKind {
|
||||||
self.types[ty.0].clone().stable(self)
|
let mut tables = self.0.borrow_mut();
|
||||||
|
tables.types[ty.0].clone().stable(&mut *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_ty(&mut self, kind: TyKind) -> stable_mir::ty::Ty {
|
fn mk_ty(&self, kind: TyKind) -> stable_mir::ty::Ty {
|
||||||
let n = self.types.len();
|
let mut tables = self.0.borrow_mut();
|
||||||
self.types.push(MaybeStable::Stable(kind));
|
let n = tables.types.len();
|
||||||
|
tables.types.push(MaybeStable::Stable(kind));
|
||||||
stable_mir::ty::Ty(n)
|
stable_mir::ty::Ty(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generics_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
|
fn generics_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::Generics {
|
||||||
let def_id = self[def_id];
|
let mut tables = self.0.borrow_mut();
|
||||||
let generics = self.tcx.generics_of(def_id);
|
let def_id = tables[def_id];
|
||||||
generics.stable(self)
|
let generics = tables.tcx.generics_of(def_id);
|
||||||
|
generics.stable(&mut *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn predicates_of(&mut self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
|
fn predicates_of(&self, def_id: stable_mir::DefId) -> stable_mir::ty::GenericPredicates {
|
||||||
let def_id = self[def_id];
|
let mut tables = self.0.borrow_mut();
|
||||||
let ty::GenericPredicates { parent, predicates } = self.tcx.predicates_of(def_id);
|
let def_id = tables[def_id];
|
||||||
|
let ty::GenericPredicates { parent, predicates } = tables.tcx.predicates_of(def_id);
|
||||||
stable_mir::ty::GenericPredicates {
|
stable_mir::ty::GenericPredicates {
|
||||||
parent: parent.map(|did| self.trait_def(did)),
|
parent: parent.map(|did| tables.trait_def(did)),
|
||||||
predicates: predicates
|
predicates: predicates
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(clause, span)| {
|
.map(|(clause, span)| {
|
||||||
(clause.as_predicate().kind().skip_binder().stable(self), span.stable(self))
|
(
|
||||||
|
clause.as_predicate().kind().skip_binder().stable(&mut *tables),
|
||||||
|
span.stable(&mut *tables),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn explicit_predicates_of(
|
fn explicit_predicates_of(
|
||||||
&mut self,
|
&self,
|
||||||
def_id: stable_mir::DefId,
|
def_id: stable_mir::DefId,
|
||||||
) -> stable_mir::ty::GenericPredicates {
|
) -> stable_mir::ty::GenericPredicates {
|
||||||
let def_id = self[def_id];
|
let mut tables = self.0.borrow_mut();
|
||||||
let ty::GenericPredicates { parent, predicates } = self.tcx.explicit_predicates_of(def_id);
|
let def_id = tables[def_id];
|
||||||
|
let ty::GenericPredicates { parent, predicates } =
|
||||||
|
tables.tcx.explicit_predicates_of(def_id);
|
||||||
stable_mir::ty::GenericPredicates {
|
stable_mir::ty::GenericPredicates {
|
||||||
parent: parent.map(|did| self.trait_def(did)),
|
parent: parent.map(|did| tables.trait_def(did)),
|
||||||
predicates: predicates
|
predicates: predicates
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(clause, span)| {
|
.map(|(clause, span)| {
|
||||||
(clause.as_predicate().kind().skip_binder().stable(self), span.stable(self))
|
(
|
||||||
|
clause.as_predicate().kind().skip_binder().stable(&mut *tables),
|
||||||
|
span.stable(&mut *tables),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instance_body(&mut self, def: InstanceDef) -> Body {
|
fn instance_body(&self, def: InstanceDef) -> Body {
|
||||||
let instance = self.instances[def];
|
let mut tables = self.0.borrow_mut();
|
||||||
builder::BodyBuilder::new(self.tcx, instance).build(self)
|
let instance = tables.instances[def];
|
||||||
|
builder::BodyBuilder::new(tables.tcx, instance).build(&mut *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instance_ty(&mut self, def: InstanceDef) -> stable_mir::ty::Ty {
|
fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
|
||||||
let instance = self.instances[def];
|
let mut tables = self.0.borrow_mut();
|
||||||
let ty = instance.ty(self.tcx, ParamEnv::empty());
|
let instance = tables.instances[def];
|
||||||
self.intern_ty(ty)
|
let ty = instance.ty(tables.tcx, ParamEnv::empty());
|
||||||
|
tables.intern_ty(ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn instance_def_id(&mut self, def: InstanceDef) -> stable_mir::DefId {
|
fn instance_def_id(&self, def: InstanceDef) -> stable_mir::DefId {
|
||||||
let def_id = self.instances[def].def_id();
|
let mut tables = self.0.borrow_mut();
|
||||||
self.create_def_id(def_id)
|
let def_id = tables.instances[def].def_id();
|
||||||
|
tables.create_def_id(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mono_instance(&mut self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
|
fn mono_instance(&self, item: stable_mir::CrateItem) -> stable_mir::mir::mono::Instance {
|
||||||
let def_id = self[item.0];
|
let mut tables = self.0.borrow_mut();
|
||||||
Instance::mono(self.tcx, def_id).stable(self)
|
let def_id = tables[item.0];
|
||||||
|
Instance::mono(tables.tcx, def_id).stable(&mut *tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool {
|
fn requires_monomorphization(&self, def_id: stable_mir::DefId) -> bool {
|
||||||
let def_id = self[def_id];
|
let tables = self.0.borrow();
|
||||||
let generics = self.tcx.generics_of(def_id);
|
let def_id = tables[def_id];
|
||||||
let result = generics.requires_monomorphization(self.tcx);
|
let generics = tables.tcx.generics_of(def_id);
|
||||||
|
let result = generics.requires_monomorphization(tables.tcx);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_instance(
|
fn resolve_instance(
|
||||||
&mut self,
|
&self,
|
||||||
def: stable_mir::ty::FnDef,
|
def: stable_mir::ty::FnDef,
|
||||||
args: &stable_mir::ty::GenericArgs,
|
args: &stable_mir::ty::GenericArgs,
|
||||||
) -> Option<stable_mir::mir::mono::Instance> {
|
) -> Option<stable_mir::mir::mono::Instance> {
|
||||||
let def_id = def.0.internal(self);
|
let mut tables = self.0.borrow_mut();
|
||||||
let args_ref = args.internal(self);
|
let def_id = def.0.internal(&mut *tables);
|
||||||
match Instance::resolve(self.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
|
let args_ref = args.internal(&mut *tables);
|
||||||
Ok(Some(instance)) => Some(instance.stable(self)),
|
match Instance::resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) {
|
||||||
|
Ok(Some(instance)) => Some(instance.stable(&mut *tables)),
|
||||||
Ok(None) | Err(_) => None,
|
Ok(None) | Err(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,13 +279,15 @@ impl<S, R: PartialEq> PartialEq<R> for MaybeStable<S, R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct TablesWrapper<'tcx>(pub(crate) std::rc::Rc<RefCell<Tables<'tcx>>>);
|
||||||
|
|
||||||
pub struct Tables<'tcx> {
|
pub struct Tables<'tcx> {
|
||||||
pub tcx: TyCtxt<'tcx>,
|
pub(crate) tcx: TyCtxt<'tcx>,
|
||||||
pub def_ids: IndexMap<DefId, stable_mir::DefId>,
|
pub(crate) def_ids: IndexMap<DefId, stable_mir::DefId>,
|
||||||
pub alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
|
pub(crate) alloc_ids: IndexMap<AllocId, stable_mir::AllocId>,
|
||||||
pub spans: IndexMap<rustc_span::Span, Span>,
|
pub(crate) spans: IndexMap<rustc_span::Span, Span>,
|
||||||
pub types: Vec<MaybeStable<TyKind, Ty<'tcx>>>,
|
pub(crate) types: Vec<MaybeStable<TyKind, Ty<'tcx>>>,
|
||||||
pub instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
|
pub(crate) instances: IndexMap<ty::Instance<'tcx>, InstanceDef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Tables<'tcx> {
|
impl<'tcx> Tables<'tcx> {
|
||||||
|
@ -270,7 +310,7 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait used to convert between an internal MIR type to a Stable MIR type.
|
/// Trait used to convert between an internal MIR type to a Stable MIR type.
|
||||||
pub(crate) trait Stable<'tcx> {
|
pub trait Stable<'tcx> {
|
||||||
/// The stable representation of the type implementing Stable.
|
/// The stable representation of the type implementing Stable.
|
||||||
type T;
|
type T;
|
||||||
/// Converts an object to the equivalent Stable MIR representation.
|
/// Converts an object to the equivalent Stable MIR representation.
|
||||||
|
|
|
@ -175,17 +175,17 @@ pub fn trait_impl(trait_impl: &ImplDef) -> ImplTrait {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Context {
|
pub trait Context {
|
||||||
fn entry_fn(&mut self) -> Option<CrateItem>;
|
fn entry_fn(&self) -> Option<CrateItem>;
|
||||||
/// Retrieve all items of the local crate that have a MIR associated with them.
|
/// Retrieve all items of the local crate that have a MIR associated with them.
|
||||||
fn all_local_items(&mut self) -> CrateItems;
|
fn all_local_items(&self) -> CrateItems;
|
||||||
fn mir_body(&mut self, item: DefId) -> mir::Body;
|
fn mir_body(&self, item: DefId) -> mir::Body;
|
||||||
fn all_trait_decls(&mut self) -> TraitDecls;
|
fn all_trait_decls(&self) -> TraitDecls;
|
||||||
fn trait_decl(&mut self, trait_def: &TraitDef) -> TraitDecl;
|
fn trait_decl(&self, trait_def: &TraitDef) -> TraitDecl;
|
||||||
fn all_trait_impls(&mut self) -> ImplTraitDecls;
|
fn all_trait_impls(&self) -> ImplTraitDecls;
|
||||||
fn trait_impl(&mut self, trait_impl: &ImplDef) -> ImplTrait;
|
fn trait_impl(&self, trait_impl: &ImplDef) -> ImplTrait;
|
||||||
fn generics_of(&mut self, def_id: DefId) -> Generics;
|
fn generics_of(&self, def_id: DefId) -> Generics;
|
||||||
fn predicates_of(&mut self, def_id: DefId) -> GenericPredicates;
|
fn predicates_of(&self, def_id: DefId) -> GenericPredicates;
|
||||||
fn explicit_predicates_of(&mut self, def_id: DefId) -> GenericPredicates;
|
fn explicit_predicates_of(&self, def_id: DefId) -> GenericPredicates;
|
||||||
/// Get information about the local crate.
|
/// Get information about the local crate.
|
||||||
fn local_crate(&self) -> Crate;
|
fn local_crate(&self) -> Crate;
|
||||||
/// Retrieve a list of all external crates.
|
/// Retrieve a list of all external crates.
|
||||||
|
@ -207,61 +207,61 @@ pub trait Context {
|
||||||
fn get_lines(&self, span: &Span) -> LineInfo;
|
fn get_lines(&self, span: &Span) -> LineInfo;
|
||||||
|
|
||||||
/// Returns the `kind` of given `DefId`
|
/// Returns the `kind` of given `DefId`
|
||||||
fn def_kind(&mut self, def_id: DefId) -> DefKind;
|
fn def_kind(&self, def_id: DefId) -> DefKind;
|
||||||
|
|
||||||
/// `Span` of an item
|
/// `Span` of an item
|
||||||
fn span_of_an_item(&mut self, def_id: DefId) -> Span;
|
fn span_of_an_item(&self, def_id: DefId) -> Span;
|
||||||
|
|
||||||
/// Obtain the representation of a type.
|
/// Obtain the representation of a type.
|
||||||
fn ty_kind(&mut self, ty: Ty) -> TyKind;
|
fn ty_kind(&self, ty: Ty) -> TyKind;
|
||||||
|
|
||||||
/// Create a new `Ty` from scratch without information from rustc.
|
/// Create a new `Ty` from scratch without information from rustc.
|
||||||
fn mk_ty(&mut self, kind: TyKind) -> Ty;
|
fn mk_ty(&self, kind: TyKind) -> Ty;
|
||||||
|
|
||||||
/// Get the body of an Instance.
|
/// Get the body of an Instance.
|
||||||
/// FIXME: Monomorphize the body.
|
/// FIXME: Monomorphize the body.
|
||||||
fn instance_body(&mut self, instance: InstanceDef) -> Body;
|
fn instance_body(&self, instance: InstanceDef) -> Body;
|
||||||
|
|
||||||
/// Get the instance type with generic substitutions applied and lifetimes erased.
|
/// Get the instance type with generic substitutions applied and lifetimes erased.
|
||||||
fn instance_ty(&mut self, instance: InstanceDef) -> Ty;
|
fn instance_ty(&self, instance: InstanceDef) -> Ty;
|
||||||
|
|
||||||
/// Get the instance.
|
/// Get the instance.
|
||||||
fn instance_def_id(&mut self, instance: InstanceDef) -> DefId;
|
fn instance_def_id(&self, instance: InstanceDef) -> DefId;
|
||||||
|
|
||||||
/// Convert a non-generic crate item into an instance.
|
/// Convert a non-generic crate item into an instance.
|
||||||
/// This function will panic if the item is generic.
|
/// This function will panic if the item is generic.
|
||||||
fn mono_instance(&mut self, item: CrateItem) -> Instance;
|
fn mono_instance(&self, item: CrateItem) -> Instance;
|
||||||
|
|
||||||
/// Item requires monomorphization.
|
/// Item requires monomorphization.
|
||||||
fn requires_monomorphization(&self, def_id: DefId) -> bool;
|
fn requires_monomorphization(&self, def_id: DefId) -> bool;
|
||||||
|
|
||||||
/// Resolve an instance from the given function definition and generic arguments.
|
/// Resolve an instance from the given function definition and generic arguments.
|
||||||
fn resolve_instance(&mut self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
|
fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option<Instance>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
|
// A thread local variable that stores a pointer to the tables mapping between TyCtxt
|
||||||
// datastructures and stable MIR datastructures
|
// datastructures and stable MIR datastructures
|
||||||
scoped_thread_local! (static TLV: Cell<*mut ()>);
|
scoped_thread_local! (static TLV: Cell<*const ()>);
|
||||||
|
|
||||||
pub fn run(mut context: impl Context, f: impl FnOnce()) {
|
pub fn run(context: impl Context, f: impl FnOnce()) {
|
||||||
assert!(!TLV.is_set());
|
assert!(!TLV.is_set());
|
||||||
fn g<'a>(mut context: &mut (dyn Context + 'a), f: impl FnOnce()) {
|
fn g<'a>(context: &(dyn Context + 'a), f: impl FnOnce()) {
|
||||||
let ptr: *mut () = &mut context as *mut &mut _ as _;
|
let ptr: *const () = &context as *const &_ as _;
|
||||||
TLV.set(&Cell::new(ptr), || {
|
TLV.set(&Cell::new(ptr), || {
|
||||||
f();
|
f();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
g(&mut context, f);
|
g(&context, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Loads the current context and calls a function with it.
|
/// Loads the current context and calls a function with it.
|
||||||
/// Do not nest these, as that will ICE.
|
/// Do not nest these, as that will ICE.
|
||||||
pub fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
|
pub fn with<R>(f: impl FnOnce(&dyn Context) -> R) -> R {
|
||||||
assert!(TLV.is_set());
|
assert!(TLV.is_set());
|
||||||
TLV.with(|tlv| {
|
TLV.with(|tlv| {
|
||||||
let ptr = tlv.get();
|
let ptr = tlv.get();
|
||||||
assert!(!ptr.is_null());
|
assert!(!ptr.is_null());
|
||||||
f(unsafe { *(ptr as *mut &mut dyn Context) })
|
f(unsafe { *(ptr as *const &dyn Context) })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue