fix: resolve the unsoundness

add a new trait `InternalCx`, which defines the methods that are fine to call from `RustcInternal`. `RustcInternal::internal()` then takes a `impl InternalCx<'tcx>` instead of `TyCtxt<'tcx>`.

make `tcx` in `SmirCtxt` public, since we need to pass it to `RustcInternal::internal()` in `SmirInterface`.
This commit is contained in:
Makai 2025-06-09 08:13:27 +00:00
parent b5a2e7d080
commit efa26e1d64
8 changed files with 422 additions and 288 deletions

View file

@ -43,11 +43,14 @@ pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
/// # Panics
///
/// This function will panic if StableMIR has not been properly initialized.
pub fn internal<'tcx, S>(item: S) -> S::T<'tcx>
pub fn internal<'tcx, S>(tcx: TyCtxt<'tcx>, item: S) -> S::T<'tcx>
where
S: RustcInternal,
{
with_container(|tables, cx| item.internal(tables, cx))
// The tcx argument ensures that the item won't outlive the type context.
// See https://github.com/rust-lang/rust/pull/120128/commits/9aace6723572438a94378451793ca37deb768e72
// for more details.
with_container(|tables, _| item.internal(tables, tcx))
}
pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
@ -69,14 +72,14 @@ where
/// Loads the current context and calls a function with it.
/// Do not nest these, as that will ICE.
pub(crate) fn with_container<'tcx, R, B: Bridge>(
f: impl FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R,
pub(crate) fn with_container<R, B: Bridge>(
f: impl for<'tcx> FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R,
) -> R {
assert!(TLV.is_set());
TLV.with(|tlv| {
let ptr = tlv.get();
assert!(!ptr.is_null());
let container = ptr as *const SmirContainer<'tcx, B>;
let container = ptr as *const SmirContainer<'_, B>;
let mut tables = unsafe { (*container).tables.borrow_mut() };
let cx = unsafe { (*container).cx.borrow() };
f(&mut *tables, &*cx)

View file

@ -43,8 +43,8 @@ pub fn try_new_slice<'tcx, B: Bridge>(
) -> Result<Allocation, B::Error> {
let alloc_id = cx.tcx.reserve_and_set_memory_alloc(data);
let ptr = Pointer::new(alloc_id.into(), Size::ZERO);
let scalar_ptr = Scalar::from_pointer(ptr, &tables.tcx);
let scalar_meta: Scalar = Scalar::from_target_usize(meta, &tables.tcx);
let scalar_ptr = Scalar::from_pointer(ptr, &cx.tcx);
let scalar_meta: Scalar = Scalar::from_target_usize(meta, &cx.tcx);
let mut allocation = Allocation::new(layout.size, layout.align.abi, AllocInit::Uninit, ());
allocation
.write_scalar(&cx.tcx, alloc_range(Size::ZERO, cx.tcx.data_layout.pointer_size), scalar_ptr)

View file

@ -25,44 +25,10 @@ use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_span::{FileNameDisplayPreference, Span, Symbol};
use rustc_target::callconv::FnAbi;
use super::{
SmirAllocRange, SmirCtxt, SmirExistentialProjection, SmirExistentialTraitRef, SmirRegion,
SmirTraitRef, SmirTy, SmirTypingEnv,
};
use super::{SmirAllocRange, SmirCtxt, SmirTy, SmirTypingEnv};
use crate::rustc_smir::builder::BodyBuilder;
use crate::rustc_smir::{Bridge, SmirError, Tables, filter_def_ids};
impl<'tcx, B: Bridge> SmirExistentialProjection<'tcx> for SmirCtxt<'tcx, B> {
fn new_from_args(
&self,
def_id: rustc_span::def_id::DefId,
args: ty::GenericArgsRef<'tcx>,
term: ty::Term<'tcx>,
) -> ty::ExistentialProjection<'tcx> {
ty::ExistentialProjection::new_from_args(self.tcx, def_id, args, term)
}
}
impl<'tcx, B: Bridge> SmirExistentialTraitRef<'tcx> for SmirCtxt<'tcx, B> {
fn new_from_args(
&self,
trait_def_id: DefId,
args: ty::GenericArgsRef<'tcx>,
) -> ty::ExistentialTraitRef<'tcx> {
ty::ExistentialTraitRef::new_from_args(self.tcx, trait_def_id, args)
}
}
impl<'tcx, B: Bridge> SmirTraitRef<'tcx> for SmirCtxt<'tcx, B> {
fn new_from_args(
&self,
trait_def_id: DefId,
args: ty::GenericArgsRef<'tcx>,
) -> ty::TraitRef<'tcx> {
ty::TraitRef::new_from_args(self.tcx, trait_def_id, args)
}
}
impl<'tcx, B: Bridge> SmirTy<'tcx> for SmirCtxt<'tcx, B> {
fn new_foreign(&self, def_id: DefId) -> ty::Ty<'tcx> {
ty::Ty::new_foreign(self.tcx, def_id)
@ -85,52 +51,11 @@ impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> {
}
}
impl<'tcx, B: Bridge> SmirRegion<'tcx> for SmirCtxt<'tcx, B> {
fn lifetimes_re_erased(&self) -> ty::Region<'tcx> {
self.tcx.lifetimes.re_erased
}
}
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
pub fn lift<T: ty::Lift<TyCtxt<'tcx>>>(&self, value: T) -> Option<T::Lifted> {
self.tcx.lift(value)
}
pub fn mk_args_from_iter<I, T>(&self, iter: I) -> T::Output
where
I: Iterator<Item = T>,
T: ty::CollectAndApply<ty::GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
{
self.tcx.mk_args_from_iter(iter)
}
pub fn mk_pat(&self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx> {
self.tcx.mk_pat(v)
}
pub fn mk_poly_existential_predicates(
&self,
eps: &[ty::PolyExistentialPredicate<'tcx>],
) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
self.tcx.mk_poly_existential_predicates(eps)
}
pub fn mk_type_list(&self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
self.tcx.mk_type_list(v)
}
pub fn mk_bound_variable_kinds_from_iter<I, T>(&self, iter: I) -> T::Output
where
I: Iterator<Item = T>,
T: ty::CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
{
self.tcx.mk_bound_variable_kinds_from_iter(iter)
}
pub fn mk_place_elems(&self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List<mir::PlaceElem<'tcx>> {
self.tcx.mk_place_elems(v)
}
pub fn adt_def(&self, def_id: DefId) -> AdtDef<'tcx> {
self.tcx.adt_def(def_id)
}

View file

@ -21,12 +21,12 @@ pub use traits::*;
/// The [`crate::stable_mir::compiler_interface::SmirInterface`] must go through
/// this context to obtain rustc-level information.
pub struct SmirCtxt<'tcx, B: Bridge> {
pub(crate) tcx: TyCtxt<'tcx>,
pub tcx: TyCtxt<'tcx>,
_marker: PhantomData<B>,
}
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self {
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
Self { tcx, _marker: Default::default() }
}
}

View file

@ -44,7 +44,3 @@ pub trait SmirTypingEnv<'tcx> {
pub trait SmirAllocRange<'tcx> {
fn alloc_range(&self, offset: rustc_abi::Size, size: rustc_abi::Size) -> AllocRange;
}
pub trait SmirRegion<'tcx> {
fn lifetimes_re_erased(&self) -> ty::Region<'tcx>;
}

View file

@ -6,6 +6,7 @@
use std::cell::Cell;
use rustc_hir::def::DefKind;
use rustc_smir::context::SmirCtxt;
use rustc_smir::{Bridge, SmirContainer};
use stable_mir::abi::{FnAbi, Layout, LayoutShape, ReprOptions};
use stable_mir::convert::{RustcInternal, Stable};
@ -327,16 +328,15 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
/// Check whether the body of a function is available.
fn has_body(&self, item: DefId) -> bool {
let mut tables = self.tables.borrow_mut();
let tables_ref = &mut *tables;
let cx = &*self.cx.borrow();
let def = item.internal(tables_ref, cx);
let def = item.internal(&mut *tables, cx.tcx);
cx.has_body(def)
}
fn foreign_modules(&self, crate_num: CrateNum) -> Vec<ForeignModuleDef> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cx.foreign_modules(crate_num.internal(&mut *tables, cx))
cx.foreign_modules(crate_num.internal(&mut *tables, cx.tcx))
.iter()
.map(|did| tables.foreign_module_def(*did))
.collect()
@ -346,7 +346,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn crate_functions(&self, crate_num: CrateNum) -> Vec<FnDef> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let krate = crate_num.internal(&mut *tables, cx);
let krate = crate_num.internal(&mut *tables, cx.tcx);
cx.crate_functions(krate).iter().map(|did| tables.fn_def(*did)).collect()
}
@ -354,7 +354,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn crate_statics(&self, crate_num: CrateNum) -> Vec<StaticDef> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let krate = crate_num.internal(&mut *tables, cx);
let krate = crate_num.internal(&mut *tables, cx.tcx);
cx.crate_statics(krate).iter().map(|did| tables.static_def(*did)).collect()
}
@ -381,7 +381,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn trait_decls(&self, crate_num: CrateNum) -> TraitDecls {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let krate = crate_num.internal(&mut *tables, cx);
let krate = crate_num.internal(&mut *tables, cx.tcx);
cx.trait_decls(krate).iter().map(|did| tables.trait_def(*did)).collect()
}
@ -401,7 +401,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn trait_impls(&self, crate_num: CrateNum) -> ImplTraitDecls {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let krate = crate_num.internal(&mut *tables, cx);
let krate = crate_num.internal(&mut *tables, cx.tcx);
cx.trait_impls(krate).iter().map(|did| tables.impl_def(*did)).collect()
}
@ -461,19 +461,19 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
/// Get information about the local crate.
fn local_crate(&self) -> Crate {
let cx = &*self.cx.borrow();
self.smir_crate(cx.local_crate_num())
smir_crate(cx, cx.local_crate_num())
}
/// Retrieve a list of all external crates.
fn external_crates(&self) -> Vec<Crate> {
let cx = &*self.cx.borrow();
cx.external_crates().iter().map(|crate_num| self.smir_crate(*crate_num)).collect()
cx.external_crates().iter().map(|crate_num| smir_crate(cx, *crate_num)).collect()
}
/// Find a crate with the given name.
fn find_crates(&self, name: &str) -> Vec<Crate> {
let cx = &*self.cx.borrow();
cx.find_crates(name).iter().map(|crate_num| self.smir_crate(*crate_num)).collect()
cx.find_crates(name).iter().map(|crate_num| smir_crate(cx, *crate_num)).collect()
}
/// Returns the name of given `DefId`.
@ -574,28 +574,28 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn adt_kind(&self, def: AdtDef) -> AdtKind {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cx.adt_kind(def.internal(&mut *tables, cx)).stable(&mut *tables, cx)
cx.adt_kind(def.internal(&mut *tables, cx.tcx)).stable(&mut *tables, cx)
}
/// Returns if the ADT is a box.
fn adt_is_box(&self, def: AdtDef) -> bool {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cx.adt_is_box(def.internal(&mut *tables, cx))
cx.adt_is_box(def.internal(&mut *tables, cx.tcx))
}
/// Returns whether this ADT is simd.
fn adt_is_simd(&self, def: AdtDef) -> bool {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cx.adt_is_simd(def.internal(&mut *tables, cx))
cx.adt_is_simd(def.internal(&mut *tables, cx.tcx))
}
/// Returns whether this definition is a C string.
fn adt_is_cstr(&self, def: AdtDef) -> bool {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cx.adt_is_cstr(def.0.internal(&mut *tables, cx))
cx.adt_is_cstr(def.0.internal(&mut *tables, cx.tcx))
}
/// Returns the representation options for this ADT
@ -607,8 +607,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let def_id = def.0.internal(&mut *tables, cx);
let args_ref = args.internal(&mut *tables, cx);
let def_id = def.0.internal(&mut *tables, cx.tcx);
let args_ref = args.internal(&mut *tables, cx.tcx);
cx.fn_sig(def_id, args_ref).stable(&mut *tables, cx)
}
@ -616,7 +616,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn intrinsic(&self, item: DefId) -> Option<IntrinsicDef> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let def_id = item.internal(&mut *tables, cx);
let def_id = item.internal(&mut *tables, cx.tcx);
cx.intrinsic(def_id).map(|_| IntrinsicDef(item))
}
@ -624,7 +624,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn intrinsic_name(&self, def: IntrinsicDef) -> Symbol {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let def_id = def.0.internal(&mut *tables, cx);
let def_id = def.0.internal(&mut *tables, cx.tcx);
cx.intrinsic_name(def_id)
}
@ -632,7 +632,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let args_ref = args.internal(&mut *tables, cx);
let args_ref = args.internal(&mut *tables, cx.tcx);
cx.closure_sig(args_ref).stable(&mut *tables, cx)
}
@ -640,7 +640,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn adt_variants_len(&self, def: AdtDef) -> usize {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cx.adt_variants_len(def.internal(&mut *tables, cx))
cx.adt_variants_len(def.internal(&mut *tables, cx.tcx))
}
/// Discriminant for a given variant index of AdtDef
@ -662,27 +662,31 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn variant_name(&self, def: VariantDef) -> Symbol {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cx.variant_name(def.internal(&mut *tables, cx))
cx.variant_name(def.internal(&mut *tables, cx.tcx))
}
fn variant_fields(&self, def: VariantDef) -> Vec<FieldDef> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
def.internal(&mut *tables, cx).fields.iter().map(|f| f.stable(&mut *tables, cx)).collect()
def.internal(&mut *tables, cx.tcx)
.fields
.iter()
.map(|f| f.stable(&mut *tables, cx))
.collect()
}
/// Evaluate constant as a target usize.
fn eval_target_usize(&self, mir_const: &MirConst) -> Result<u64, Error> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let cnst = mir_const.internal(&mut *tables, cx);
let cnst = mir_const.internal(&mut *tables, cx.tcx);
cx.eval_target_usize(cnst)
}
fn eval_target_usize_ty(&self, ty_const: &TyConst) -> Result<u64, Error> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let cnst = ty_const.internal(&mut *tables, cx);
let cnst = ty_const.internal(&mut *tables, cx.tcx);
cx.eval_target_usize_ty(cnst)
}
@ -690,7 +694,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn try_new_const_zst(&self, ty: Ty) -> Result<MirConst, Error> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let ty_internal = ty.internal(&mut *tables, cx);
let ty_internal = ty.internal(&mut *tables, cx.tcx);
cx.try_new_const_zst(ty_internal).map(|cnst| cnst.stable(&mut *tables, cx))
}
@ -712,14 +716,14 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<MirConst, Error> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx));
let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx.tcx));
cx.try_new_const_uint(value, ty).map(|cnst| cnst.stable(&mut *tables, cx))
}
fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result<TyConst, Error> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx));
let ty = cx.ty_new_uint(uint_ty.internal(&mut *tables, cx.tcx));
cx.try_new_ty_const_uint(value, ty).map(|cnst| cnst.stable(&mut *tables, cx))
}
@ -727,7 +731,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn new_rigid_ty(&self, kind: RigidTy) -> Ty {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let internal_kind = kind.internal(&mut *tables, cx);
let internal_kind = kind.internal(&mut *tables, cx.tcx);
cx.new_rigid_ty(internal_kind).stable(&mut *tables, cx)
}
@ -735,7 +739,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn new_box_ty(&self, ty: Ty) -> Ty {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let inner = ty.internal(&mut *tables, cx);
let inner = ty.internal(&mut *tables, cx.tcx);
cx.new_box_ty(inner).stable(&mut *tables, cx)
}
@ -743,7 +747,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn def_ty(&self, item: DefId) -> Ty {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let inner = item.internal(&mut *tables, cx);
let inner = item.internal(&mut *tables, cx.tcx);
cx.def_ty(inner).stable(&mut *tables, cx)
}
@ -751,8 +755,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let inner = item.internal(&mut *tables, cx);
let args_ref = args.internal(&mut *tables, cx);
let inner = item.internal(&mut *tables, cx.tcx);
let args_ref = args.internal(&mut *tables, cx.tcx);
cx.def_ty_with_args(inner, args_ref).stable(&mut *tables, cx)
}
@ -760,7 +764,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn mir_const_pretty(&self, cnst: &MirConst) -> String {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
cnst.internal(&mut *tables, cx).to_string()
cnst.internal(&mut *tables, cx.tcx).to_string()
}
/// `Span` of an item.
@ -795,7 +799,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> Ty {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let internal_kind = ty.internal(&mut *tables, cx);
let internal_kind = ty.internal(&mut *tables, cx.tcx);
cx.rigid_ty_discriminant_ty(internal_kind).stable(&mut *tables, cx)
}
@ -868,8 +872,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn resolve_instance(&self, def: FnDef, args: &GenericArgs) -> Option<Instance> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let def_id = def.0.internal(&mut *tables, cx);
let args_ref = args.internal(&mut *tables, cx);
let def_id = def.0.internal(&mut *tables, cx.tcx);
let args_ref = args.internal(&mut *tables, cx.tcx);
cx.resolve_instance(def_id, args_ref).map(|inst| inst.stable(&mut *tables, cx))
}
@ -877,7 +881,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn resolve_drop_in_place(&self, ty: Ty) -> Instance {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let internal_ty = ty.internal(&mut *tables, cx);
let internal_ty = ty.internal(&mut *tables, cx.tcx);
cx.resolve_drop_in_place(internal_ty).stable(&mut *tables, cx)
}
@ -886,8 +890,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn resolve_for_fn_ptr(&self, def: FnDef, args: &GenericArgs) -> Option<Instance> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let def_id = def.0.internal(&mut *tables, cx);
let args_ref = args.internal(&mut *tables, cx);
let def_id = def.0.internal(&mut *tables, cx.tcx);
let args_ref = args.internal(&mut *tables, cx.tcx);
cx.resolve_for_fn_ptr(def_id, args_ref).stable(&mut *tables, cx)
}
@ -900,9 +904,9 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
) -> Option<Instance> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let def_id = def.0.internal(&mut *tables, cx);
let args_ref = args.internal(&mut *tables, cx);
let closure_kind = kind.internal(&mut *tables, cx);
let def_id = def.0.internal(&mut *tables, cx.tcx);
let args_ref = args.internal(&mut *tables, cx.tcx);
let closure_kind = kind.internal(&mut *tables, cx.tcx);
cx.resolve_closure(def_id, args_ref, closure_kind).map(|inst| inst.stable(&mut *tables, cx))
}
@ -910,7 +914,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn eval_static_initializer(&self, def: StaticDef) -> Result<Allocation, Error> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let def_id = def.0.internal(&mut *tables, cx);
let def_id = def.0.internal(&mut *tables, cx.tcx);
cx.eval_static_initializer(def_id).stable(&mut *tables, cx)
}
@ -920,7 +924,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
let mut tables = self.tables.borrow_mut();
let instance = tables.instances[def];
let cx = &*self.cx.borrow();
let const_ty = const_ty.internal(&mut *tables, cx);
let const_ty = const_ty.internal(&mut *tables, cx.tcx);
cx.eval_instance(instance)
.map(|const_val| alloc::try_new_allocation(const_ty, const_val, &mut *tables, cx))
.map_err(|e| e.stable(&mut *tables, cx))?
@ -930,7 +934,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn global_alloc(&self, id: AllocId) -> GlobalAlloc {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let alloc_id = id.internal(&mut *tables, cx);
let alloc_id = id.internal(&mut *tables, cx.tcx);
cx.global_alloc(alloc_id).stable(&mut *tables, cx)
}
@ -941,15 +945,16 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
return None;
};
let cx = &*self.cx.borrow();
let ty = ty.internal(&mut *tables, cx);
let trait_ref = trait_ref.internal(&mut *tables, cx);
let ty = ty.internal(&mut *tables, cx.tcx);
let trait_ref = trait_ref.internal(&mut *tables, cx.tcx);
let alloc_id = cx.vtable_allocation(ty, trait_ref);
Some(alloc_id.stable(&mut *tables, cx))
}
fn krate(&self, def_id: DefId) -> Crate {
let tables = self.tables.borrow();
self.smir_crate(tables[def_id].krate)
let cx = &*self.cx.borrow();
smir_crate(cx, tables[def_id].krate)
}
fn instance_name(&self, def: InstanceDef, trimmed: bool) -> Symbol {
@ -981,7 +986,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn fn_ptr_abi(&self, fn_ptr: PolyFnSig) -> Result<FnAbi, Error> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let sig = fn_ptr.internal(&mut *tables, cx);
let sig = fn_ptr.internal(&mut *tables, cx.tcx);
cx.fn_ptr_abi(sig).map(|fn_abi| fn_abi.stable(&mut *tables, cx))
}
@ -989,7 +994,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn ty_layout(&self, ty: Ty) -> Result<Layout, Error> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let internal_ty = ty.internal(&mut *tables, cx);
let internal_ty = ty.internal(&mut *tables, cx.tcx);
cx.ty_layout(internal_ty).map(|layout| layout.stable(&mut *tables, cx))
}
@ -997,7 +1002,7 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn layout_shape(&self, id: Layout) -> LayoutShape {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
id.internal(&mut *tables, cx).0.stable(&mut *tables, cx)
id.internal(&mut *tables, cx.tcx).0.stable(&mut *tables, cx)
}
/// Get a debug string representation of a place.
@ -1005,16 +1010,16 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
format!("{:?}", place.internal(&mut *tables, cx))
format!("{:?}", place.internal(&mut *tables, cx.tcx))
}
/// Get the resulting type of binary operation.
fn binop_ty(&self, bin_op: BinOp, rhs: Ty, lhs: Ty) -> Ty {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let rhs_internal = rhs.internal(&mut *tables, cx);
let lhs_internal = lhs.internal(&mut *tables, cx);
let bin_op_internal = bin_op.internal(&mut *tables, cx);
let rhs_internal = rhs.internal(&mut *tables, cx.tcx);
let lhs_internal = lhs.internal(&mut *tables, cx.tcx);
let bin_op_internal = bin_op.internal(&mut *tables, cx.tcx);
cx.binop_ty(bin_op_internal, rhs_internal, lhs_internal).stable(&mut *tables, cx)
}
@ -1022,8 +1027,8 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
fn unop_ty(&self, un_op: UnOp, arg: Ty) -> Ty {
let mut tables = self.tables.borrow_mut();
let cx = &*self.cx.borrow();
let un_op = un_op.internal(&mut *tables, cx);
let arg = arg.internal(&mut *tables, cx);
let un_op = un_op.internal(&mut *tables, cx.tcx);
let arg = arg.internal(&mut *tables, cx.tcx);
cx.unop_ty(un_op, arg).stable(&mut *tables, cx)
}
@ -1036,21 +1041,6 @@ impl<'tcx> SmirInterface for SmirContainer<'tcx, BridgeTys> {
}
}
impl<'tcx> Helper for SmirContainer<'tcx, BridgeTys> {
fn smir_crate(&self, crate_num: rustc_span::def_id::CrateNum) -> Crate {
let cx = &*self.cx.borrow();
let name = cx.crate_name(crate_num);
let is_local = cx.crate_is_local(crate_num);
let id = cx.crate_num_id(crate_num);
debug!(?name, ?crate_num, "smir_crate");
Crate { id, name, is_local }
}
}
trait Helper {
fn smir_crate(&self, crate_num: rustc_span::def_id::CrateNum) -> Crate;
}
// A thread local variable that stores a pointer to [`SmirInterface`].
scoped_tls::scoped_thread_local!(static TLV: Cell<*const ()>);
@ -1078,3 +1068,14 @@ pub(crate) fn with<R>(f: impl FnOnce(&dyn SmirInterface) -> R) -> R {
f(unsafe { *(ptr as *const &dyn SmirInterface) })
})
}
fn smir_crate<'tcx>(
cx: &SmirCtxt<'tcx, BridgeTys>,
crate_num: rustc_span::def_id::CrateNum,
) -> Crate {
let name = cx.crate_name(crate_num);
let is_local = cx.crate_is_local(crate_num);
let id = cx.crate_num_id(crate_num);
debug!(?name, ?crate_num, "smir_crate");
Crate { id, name, is_local }
}

View file

@ -6,12 +6,11 @@
// Prefer importing stable_mir over internal rustc constructs to make this file more readable.
use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy};
use rustc_smir::context::SmirCtxt;
use rustc_smir::{IndexedVal, Tables};
use rustc_smir::Tables;
use rustc_span::Symbol;
use stable_mir::abi::Layout;
use stable_mir::compiler_interface::BridgeTys;
use stable_mir::convert::RustcInternal;
use stable_mir::unstable::{RustcInternal, InternalCx};
use stable_mir::mir::alloc::AllocId;
use stable_mir::mir::mono::{Instance, MonoItem, StaticDef};
use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, RawPtrKind, Safety, UnOp};
@ -21,18 +20,19 @@ use stable_mir::ty::{
GenericArgKind, GenericArgs, IntTy, MirConst, Movability, Pattern, Region, RigidTy, Span,
TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx,
};
use stable_mir::{CrateItem, CrateNum, DefId};
use stable_mir::{CrateItem, CrateNum, DefId, IndexedVal};
use crate::{rustc_smir, stable_mir};
impl RustcInternal for CrateItem {
type T<'tcx> = rustc_span::def_id::DefId;
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
self.0.internal(tables, cx)
self.0.internal(tables, tcx)
}
}
@ -41,7 +41,7 @@ impl RustcInternal for CrateNum {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
rustc_span::def_id::CrateNum::from_usize(*self)
}
@ -52,9 +52,9 @@ impl RustcInternal for DefId {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.lift(tables.def_ids[*self]).unwrap()
tcx.lift(tables.def_ids[*self]).unwrap()
}
}
@ -63,9 +63,9 @@ impl RustcInternal for GenericArgs {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables, cx)))
InternalCx::mk_args_from_iter(tcx, self.0.iter().map(|arg| arg.internal(tables, tcx)))
}
}
@ -74,14 +74,14 @@ impl RustcInternal for GenericArgKind {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
let arg: rustc_ty::GenericArg<'tcx> = match self {
GenericArgKind::Lifetime(reg) => reg.internal(tables, cx).into(),
GenericArgKind::Type(ty) => ty.internal(tables, cx).into(),
GenericArgKind::Const(cnst) => cnst.internal(tables, cx).into(),
GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(),
GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(),
GenericArgKind::Const(cnst) => cnst.internal(tables, tcx).into(),
};
cx.lift(arg).unwrap()
tcx.lift(arg).unwrap()
}
}
@ -90,11 +90,10 @@ impl RustcInternal for Region {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
// Cannot recover region. Use erased for now.
use rustc_smir::context::SmirRegion;
cx.lifetimes_re_erased()
tcx.lifetimes_re_erased()
}
}
@ -103,9 +102,9 @@ impl RustcInternal for Ty {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.lift(tables.types[*self]).unwrap()
tcx.lift(tables.types[*self]).unwrap()
}
}
@ -114,9 +113,9 @@ impl RustcInternal for TyConst {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.lift(tables.ty_consts[self.id]).unwrap()
tcx.lift(tables.ty_consts[self.id]).unwrap()
}
}
@ -125,12 +124,12 @@ impl RustcInternal for Pattern {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.mk_pat(match self {
tcx.mk_pat(match self {
Pattern::Range { start, end, include_end: _ } => rustc_ty::PatternKind::Range {
start: start.as_ref().unwrap().internal(tables, cx),
end: end.as_ref().unwrap().internal(tables, cx),
start: start.as_ref().unwrap().internal(tables, tcx),
end: end.as_ref().unwrap().internal(tables, tcx),
},
})
}
@ -142,63 +141,63 @@ impl RustcInternal for RigidTy {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
RigidTy::Bool => rustc_ty::TyKind::Bool,
RigidTy::Char => rustc_ty::TyKind::Char,
RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables, cx)),
RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables, cx)),
RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, cx)),
RigidTy::Int(int_ty) => rustc_ty::TyKind::Int(int_ty.internal(tables, tcx)),
RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables, tcx)),
RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, tcx)),
RigidTy::Never => rustc_ty::TyKind::Never,
RigidTy::Array(ty, cnst) => {
rustc_ty::TyKind::Array(ty.internal(tables, cx), cnst.internal(tables, cx))
rustc_ty::TyKind::Array(ty.internal(tables, tcx), cnst.internal(tables, tcx))
}
RigidTy::Pat(ty, pat) => {
rustc_ty::TyKind::Pat(ty.internal(tables, cx), pat.internal(tables, cx))
rustc_ty::TyKind::Pat(ty.internal(tables, tcx), pat.internal(tables, tcx))
}
RigidTy::Adt(def, args) => {
rustc_ty::TyKind::Adt(def.internal(tables, cx), args.internal(tables, cx))
rustc_ty::TyKind::Adt(def.internal(tables, tcx), args.internal(tables, tcx))
}
RigidTy::Str => rustc_ty::TyKind::Str,
RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, cx)),
RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, tcx)),
RigidTy::RawPtr(ty, mutability) => {
rustc_ty::TyKind::RawPtr(ty.internal(tables, cx), mutability.internal(tables, cx))
rustc_ty::TyKind::RawPtr(ty.internal(tables, tcx), mutability.internal(tables, tcx))
}
RigidTy::Ref(region, ty, mutability) => rustc_ty::TyKind::Ref(
region.internal(tables, cx),
ty.internal(tables, cx),
mutability.internal(tables, cx),
region.internal(tables, tcx),
ty.internal(tables, tcx),
mutability.internal(tables, tcx),
),
RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, cx)),
RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, tcx)),
RigidTy::FnDef(def, args) => {
rustc_ty::TyKind::FnDef(def.0.internal(tables, cx), args.internal(tables, cx))
rustc_ty::TyKind::FnDef(def.0.internal(tables, tcx), args.internal(tables, tcx))
}
RigidTy::FnPtr(sig) => {
let (sig_tys, hdr) = sig.internal(tables, cx).split();
let (sig_tys, hdr) = sig.internal(tables, tcx).split();
rustc_ty::TyKind::FnPtr(sig_tys, hdr)
}
RigidTy::Closure(def, args) => {
rustc_ty::TyKind::Closure(def.0.internal(tables, cx), args.internal(tables, cx))
rustc_ty::TyKind::Closure(def.0.internal(tables, tcx), args.internal(tables, tcx))
}
RigidTy::Coroutine(def, args, _mov) => {
rustc_ty::TyKind::Coroutine(def.0.internal(tables, cx), args.internal(tables, cx))
rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx))
}
RigidTy::CoroutineClosure(def, args) => rustc_ty::TyKind::CoroutineClosure(
def.0.internal(tables, cx),
args.internal(tables, cx),
def.0.internal(tables, tcx),
args.internal(tables, tcx),
),
RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness(
def.0.internal(tables, cx),
args.internal(tables, cx),
def.0.internal(tables, tcx),
args.internal(tables, tcx),
),
RigidTy::Dynamic(predicate, region, dyn_kind) => rustc_ty::TyKind::Dynamic(
cx.mk_poly_existential_predicates(&predicate.internal(tables, cx)),
region.internal(tables, cx),
dyn_kind.internal(tables, cx),
tcx.mk_poly_existential_predicates(&predicate.internal(tables, tcx)),
region.internal(tables, tcx),
dyn_kind.internal(tables, tcx),
),
RigidTy::Tuple(tys) => {
rustc_ty::TyKind::Tuple(cx.mk_type_list(&tys.internal(tables, cx)))
rustc_ty::TyKind::Tuple(tcx.mk_type_list(&tys.internal(tables, tcx)))
}
}
}
@ -210,7 +209,7 @@ impl RustcInternal for IntTy {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
IntTy::Isize => rustc_ty::IntTy::Isize,
@ -229,7 +228,7 @@ impl RustcInternal for UintTy {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
UintTy::Usize => rustc_ty::UintTy::Usize,
@ -248,7 +247,7 @@ impl RustcInternal for FloatTy {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
FloatTy::F16 => rustc_ty::FloatTy::F16,
@ -265,7 +264,7 @@ impl RustcInternal for Mutability {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
Mutability::Not => rustc_ty::Mutability::Not,
@ -280,7 +279,7 @@ impl RustcInternal for Movability {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
Movability::Static => rustc_ty::Movability::Static,
@ -295,7 +294,7 @@ impl RustcInternal for RawPtrKind {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
RawPtrKind::Mut => rustc_middle::mir::RawPtrKind::Mut,
@ -311,13 +310,13 @@ impl RustcInternal for FnSig {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.lift(rustc_ty::FnSig {
inputs_and_output: cx.mk_type_list(&self.inputs_and_output.internal(tables, cx)),
tcx.lift(rustc_ty::FnSig {
inputs_and_output: tcx.mk_type_list(&self.inputs_and_output.internal(tables, tcx)),
c_variadic: self.c_variadic,
safety: self.safety.internal(tables, cx),
abi: self.abi.internal(tables, cx),
safety: self.safety.internal(tables, tcx),
abi: self.abi.internal(tables, tcx),
})
.unwrap()
}
@ -329,7 +328,7 @@ impl RustcInternal for VariantIdx {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
rustc_abi::VariantIdx::from(self.to_index())
}
@ -341,9 +340,9 @@ impl RustcInternal for VariantDef {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
self.adt_def.internal(tables, cx).variant(self.idx.internal(tables, cx))
self.adt_def.internal(tables, tcx).variant(self.idx.internal(tables, tcx))
}
}
@ -352,21 +351,21 @@ impl RustcInternal for MirConst {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
let constant = tables.mir_consts[self.id];
match constant {
rustc_middle::mir::Const::Ty(ty, ct) => {
rustc_middle::mir::Const::Ty(cx.lift(ty).unwrap(), cx.lift(ct).unwrap())
rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap(), tcx.lift(ct).unwrap())
}
rustc_middle::mir::Const::Unevaluated(uneval, ty) => {
rustc_middle::mir::Const::Unevaluated(
cx.lift(uneval).unwrap(),
cx.lift(ty).unwrap(),
tcx.lift(uneval).unwrap(),
tcx.lift(ty).unwrap(),
)
}
rustc_middle::mir::Const::Val(const_val, ty) => {
rustc_middle::mir::Const::Val(cx.lift(const_val).unwrap(), cx.lift(ty).unwrap())
rustc_middle::mir::Const::Val(tcx.lift(const_val).unwrap(), tcx.lift(ty).unwrap())
}
}
}
@ -378,12 +377,12 @@ impl RustcInternal for MonoItem {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
use rustc_middle::mir::mono as rustc_mono;
match self {
MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables, cx)),
MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables, cx)),
MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables, tcx)),
MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables, tcx)),
MonoItem::GlobalAsm(_) => {
unimplemented!()
}
@ -397,9 +396,9 @@ impl RustcInternal for Instance {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.lift(tables.instances[self.def]).unwrap()
tcx.lift(tables.instances[self.def]).unwrap()
}
}
@ -409,9 +408,9 @@ impl RustcInternal for StaticDef {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
self.0.internal(tables, cx)
self.0.internal(tables, tcx)
}
}
@ -426,12 +425,12 @@ where
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
rustc_ty::Binder::bind_with_vars(
self.value.internal(tables, cx),
cx.mk_bound_variable_kinds_from_iter(
self.bound_vars.iter().map(|bound| bound.internal(tables, cx)),
self.value.internal(tables, tcx),
tcx.mk_bound_variable_kinds_from_iter(
self.bound_vars.iter().map(|bound| bound.internal(tables, tcx)),
),
)
}
@ -443,19 +442,19 @@ impl RustcInternal for BoundVariableKind {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
BoundVariableKind::Ty(kind) => rustc_ty::BoundVariableKind::Ty(match kind {
BoundTyKind::Anon => rustc_ty::BoundTyKind::Anon,
BoundTyKind::Param(def, symbol) => {
rustc_ty::BoundTyKind::Param(def.0.internal(tables, cx), Symbol::intern(symbol))
rustc_ty::BoundTyKind::Param(def.0.internal(tables, tcx), Symbol::intern(symbol))
}
}),
BoundVariableKind::Region(kind) => rustc_ty::BoundVariableKind::Region(match kind {
BoundRegionKind::BrAnon => rustc_ty::BoundRegionKind::Anon,
BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::Named(
def.0.internal(tables, cx),
def.0.internal(tables, tcx),
Symbol::intern(symbol),
),
BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::ClosureEnv,
@ -471,7 +470,7 @@ impl RustcInternal for DynKind {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
DynKind::Dyn => rustc_ty::DynKind::Dyn,
@ -485,17 +484,17 @@ impl RustcInternal for ExistentialPredicate {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
ExistentialPredicate::Trait(trait_ref) => {
rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, cx))
rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, tcx))
}
ExistentialPredicate::Projection(proj) => {
rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, cx))
rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, tcx))
}
ExistentialPredicate::AutoTrait(trait_def) => {
rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, cx))
rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, tcx))
}
}
}
@ -507,13 +506,13 @@ impl RustcInternal for ExistentialProjection {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
use rustc_smir::context::SmirExistentialProjection;
cx.new_from_args(
self.def_id.0.internal(tables, cx),
self.generic_args.internal(tables, cx),
self.term.internal(tables, cx),
tcx.new_from_args(
self.def_id.0.internal(tables, tcx),
self.generic_args.internal(tables, tcx),
self.term.internal(tables, tcx),
)
}
}
@ -524,11 +523,11 @@ impl RustcInternal for TermKind {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
TermKind::Type(ty) => ty.internal(tables, cx).into(),
TermKind::Const(cnst) => cnst.internal(tables, cx).into(),
TermKind::Type(ty) => ty.internal(tables, tcx).into(),
TermKind::Const(cnst) => cnst.internal(tables, tcx).into(),
}
}
}
@ -539,10 +538,10 @@ impl RustcInternal for ExistentialTraitRef {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
use rustc_smir::context::SmirExistentialTraitRef;
cx.new_from_args(self.def_id.0.internal(tables, cx), self.generic_args.internal(tables, cx))
tcx.new_from_args(self.def_id.0.internal(tables, tcx), self.generic_args.internal(tables, tcx))
}
}
@ -552,10 +551,10 @@ impl RustcInternal for TraitRef {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
use rustc_smir::context::SmirTraitRef;
cx.new_from_args(self.def_id.0.internal(tables, cx), self.args().internal(tables, cx))
tcx.new_from_args(self.def_id.0.internal(tables, tcx), self.args().internal(tables, tcx))
}
}
@ -564,9 +563,9 @@ impl RustcInternal for AllocId {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.lift(tables.alloc_ids[*self]).unwrap()
tcx.lift(tables.alloc_ids[*self]).unwrap()
}
}
@ -576,7 +575,7 @@ impl RustcInternal for ClosureKind {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
ClosureKind::Fn => rustc_ty::ClosureKind::Fn,
@ -591,9 +590,9 @@ impl RustcInternal for AdtDef {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.adt_def(self.0.internal(tables, cx))
InternalCx::adt_def(tcx, self.0.internal(tables, tcx))
}
}
@ -603,7 +602,7 @@ impl RustcInternal for Abi {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match *self {
Abi::Rust => rustc_abi::ExternAbi::Rust,
@ -643,7 +642,7 @@ impl RustcInternal for Safety {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
Safety::Unsafe => rustc_hir::Safety::Unsafe,
@ -657,7 +656,7 @@ impl RustcInternal for Span {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
tables.spans[*self]
}
@ -669,9 +668,9 @@ impl RustcInternal for Layout {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
cx.lift(tables.layouts[*self]).unwrap()
tcx.lift(tables.layouts[*self]).unwrap()
}
}
@ -681,11 +680,11 @@ impl RustcInternal for Place {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
rustc_middle::mir::Place {
local: rustc_middle::mir::Local::from_usize(self.local),
projection: cx.mk_place_elems(&self.projection.internal(tables, cx)),
projection: tcx.mk_place_elems(&self.projection.internal(tables, tcx)),
}
}
}
@ -696,12 +695,12 @@ impl RustcInternal for ProjectionElem {
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
ProjectionElem::Deref => rustc_middle::mir::PlaceElem::Deref,
ProjectionElem::Field(idx, ty) => {
rustc_middle::mir::PlaceElem::Field((*idx).into(), ty.internal(tables, cx))
rustc_middle::mir::PlaceElem::Field((*idx).into(), ty.internal(tables, tcx))
}
ProjectionElem::Index(idx) => rustc_middle::mir::PlaceElem::Index((*idx).into()),
ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
@ -715,13 +714,13 @@ impl RustcInternal for ProjectionElem {
rustc_middle::mir::PlaceElem::Subslice { from: *from, to: *to, from_end: *from_end }
}
ProjectionElem::Downcast(idx) => {
rustc_middle::mir::PlaceElem::Downcast(None, idx.internal(tables, cx))
rustc_middle::mir::PlaceElem::Downcast(None, idx.internal(tables, tcx))
}
ProjectionElem::OpaqueCast(ty) => {
rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, cx))
rustc_middle::mir::PlaceElem::OpaqueCast(ty.internal(tables, tcx))
}
ProjectionElem::Subtype(ty) => {
rustc_middle::mir::PlaceElem::Subtype(ty.internal(tables, cx))
rustc_middle::mir::PlaceElem::Subtype(ty.internal(tables, tcx))
}
}
}
@ -733,7 +732,7 @@ impl RustcInternal for BinOp {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
BinOp::Add => rustc_middle::mir::BinOp::Add,
@ -769,7 +768,7 @@ impl RustcInternal for UnOp {
fn internal<'tcx>(
&self,
_tables: &mut Tables<'_, BridgeTys>,
_cx: &SmirCtxt<'tcx, BridgeTys>,
_tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
match self {
UnOp::Not => rustc_middle::mir::UnOp::Not,
@ -788,9 +787,9 @@ where
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
(*self).internal(tables, cx)
(*self).internal(tables, tcx)
}
}
@ -803,9 +802,9 @@ where
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
self.as_ref().map(|inner| inner.internal(tables, cx))
self.as_ref().map(|inner| inner.internal(tables, tcx))
}
}
@ -818,8 +817,8 @@ where
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
cx: &SmirCtxt<'tcx, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx> {
self.iter().map(|e| e.internal(tables, cx)).collect()
self.iter().map(|e| e.internal(tables, tcx)).collect()
}
}

View file

@ -0,0 +1,210 @@
//! Module that collects the things that have no stability guarantees.
//!
//! We want to keep StableMIR definitions and logic separate from
//! any sort of conversion and usage of internal rustc code. So we
//! restrict the usage of internal items to be inside this module.
use std::marker::PointeeSized;
use rustc_hir::def::DefKind;
use rustc_middle::ty::{List, Ty, TyCtxt};
use rustc_middle::{mir, ty};
use rustc_smir::Tables;
use rustc_smir::context::{SmirCtxt, SmirExistentialProjection, SmirExistentialTraitRef, SmirTraitRef};
use stable_mir::{CtorKind, ItemKind};
use crate::{rustc_smir, stable_mir};
use super::compiler_interface::BridgeTys;
pub(crate) mod convert;
impl<'tcx, T: InternalCx<'tcx>> SmirExistentialProjection<'tcx> for T {
fn new_from_args(
&self,
def_id: rustc_span::def_id::DefId,
args: ty::GenericArgsRef<'tcx>,
term: ty::Term<'tcx>,
) -> ty::ExistentialProjection<'tcx> {
ty::ExistentialProjection::new_from_args(self.tcx(), def_id, args, term)
}
}
impl<'tcx, T: InternalCx<'tcx>> SmirExistentialTraitRef<'tcx> for T {
fn new_from_args(
&self,
trait_def_id: rustc_span::def_id::DefId,
args: ty::GenericArgsRef<'tcx>,
) -> ty::ExistentialTraitRef<'tcx> {
ty::ExistentialTraitRef::new_from_args(self.tcx(), trait_def_id, args)
}
}
impl<'tcx, T: InternalCx<'tcx>> SmirTraitRef<'tcx> for T {
fn new_from_args(
&self,
trait_def_id: rustc_span::def_id::DefId,
args: ty::GenericArgsRef<'tcx>,
) -> ty::TraitRef<'tcx> {
ty::TraitRef::new_from_args(self.tcx(), trait_def_id, args)
}
}
impl<'tcx> InternalCx<'tcx> for TyCtxt<'tcx> {
fn tcx(self) -> TyCtxt<'tcx> {
self
}
fn lift<T: ty::Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
TyCtxt::lift(self, value)
}
fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
where
I: Iterator<Item = T>,
T: ty::CollectAndApply<ty::GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
{
TyCtxt::mk_args_from_iter(self, iter)
}
fn mk_pat(self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx> {
TyCtxt::mk_pat(self, v)
}
fn mk_poly_existential_predicates(
self,
eps: &[ty::PolyExistentialPredicate<'tcx>],
) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
TyCtxt::mk_poly_existential_predicates(self, eps)
}
fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
TyCtxt::mk_type_list(self, v)
}
fn lifetimes_re_erased(self) -> ty::Region<'tcx> {
self.lifetimes.re_erased
}
fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
where
I: Iterator<Item = T>,
T: ty::CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
{
TyCtxt::mk_bound_variable_kinds_from_iter(self, iter)
}
fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List<mir::PlaceElem<'tcx>> {
TyCtxt::mk_place_elems(self, v)
}
fn adt_def(self, def_id: rustc_hir::def_id::DefId) -> ty::AdtDef<'tcx> {
self.adt_def(def_id)
}
}
/// Trait that defines the methods that are fine to call from [`RustcInternal`].
///
/// This trait is only for [`RustcInternal`]. Any other other access to rustc's internals
/// should go through [`crate::rustc_smir::context::SmirCtxt`].
pub trait InternalCx<'tcx> : Copy + Clone {
fn tcx(self) -> TyCtxt<'tcx>;
fn lift<T: ty::Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted>;
fn mk_args_from_iter<I, T>(self, iter: I) -> T::Output
where
I: Iterator<Item = T>,
T: ty::CollectAndApply<ty::GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>;
fn mk_pat(self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx>;
fn mk_poly_existential_predicates(
self,
eps: &[ty::PolyExistentialPredicate<'tcx>],
) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>>;
fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>>;
fn lifetimes_re_erased(self) -> ty::Region<'tcx>;
fn mk_bound_variable_kinds_from_iter<I, T>(self, iter: I) -> T::Output
where
I: Iterator<Item = T>,
T: ty::CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>;
fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List<mir::PlaceElem<'tcx>>;
fn adt_def(self, def_id: rustc_hir::def_id::DefId) -> ty::AdtDef<'tcx>;
}
/// Trait used to convert between an internal MIR type to a Stable MIR type.
///
/// This trait is currently exposed to users so they can have interoperability between internal MIR
/// and StableMIR constructs. However, they should be used seldom and they have no influence
/// in this crate semver.
#[doc(hidden)]
pub trait Stable<'tcx>: PointeeSized {
/// The stable representation of the type implementing Stable.
type T;
/// Converts an object to the equivalent Stable MIR representation.
fn stable<'cx>(
&self,
tables: &mut Tables<'cx, BridgeTys>,
cx: &SmirCtxt<'cx, BridgeTys>,
) -> Self::T;
}
/// Trait used to translate a stable construct to its rustc counterpart.
///
/// This is basically a mirror of [Stable].
///
/// This trait is currently exposed to users so they can have interoperability between internal MIR
/// and StableMIR constructs. They should be used seldom as they have no stability guarantees.
#[doc(hidden)]
pub trait RustcInternal {
type T<'tcx>;
fn internal<'tcx>(
&self,
tables: &mut Tables<'_, BridgeTys>,
tcx: impl InternalCx<'tcx>,
) -> Self::T<'tcx>;
}
pub(crate) 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::Impl { .. }
| DefKind::GlobalAsm => {
unreachable!("Not a valid item kind: {kind:?}");
}
DefKind::Closure | DefKind::AssocFn | DefKind::Fn | DefKind::SyntheticCoroutineBody => {
ItemKind::Fn
}
DefKind::Const | DefKind::InlineConst | DefKind::AssocConst | DefKind::AnonConst => {
ItemKind::Const
}
DefKind::Static { .. } => ItemKind::Static,
DefKind::Ctor(_, rustc_hir::def::CtorKind::Const) => ItemKind::Ctor(CtorKind::Const),
DefKind::Ctor(_, rustc_hir::def::CtorKind::Fn) => ItemKind::Ctor(CtorKind::Fn),
}
}