From efa26e1d64c374fa9960e5bf8709937fc251816b Mon Sep 17 00:00:00 2001 From: Makai Date: Mon, 9 Jun 2025 08:13:27 +0000 Subject: [PATCH] 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`. --- compiler/rustc_smir/src/rustc_internal/mod.rs | 13 +- compiler/rustc_smir/src/rustc_smir/alloc.rs | 4 +- .../src/rustc_smir/context/impls.rs | 77 +----- .../rustc_smir/src/rustc_smir/context/mod.rs | 4 +- .../src/rustc_smir/context/traits.rs | 4 - .../src/stable_mir/compiler_interface.rs | 145 +++++----- .../{ => unstable}/convert/internal.rs | 253 +++++++++--------- .../rustc_smir/src/stable_mir/unstable/mod.rs | 210 +++++++++++++++ 8 files changed, 422 insertions(+), 288 deletions(-) rename compiler/rustc_smir/src/stable_mir/{ => unstable}/convert/internal.rs (78%) create mode 100644 compiler/rustc_smir/src/stable_mir/unstable/mod.rs diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index b99514a3b730..a8d2ab55d037 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -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( + 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) diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 6b32b5b07d87..f5412806d335 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -43,8 +43,8 @@ pub fn try_new_slice<'tcx, B: Bridge>( ) -> Result { 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) diff --git a/compiler/rustc_smir/src/rustc_smir/context/impls.rs b/compiler/rustc_smir/src/rustc_smir/context/impls.rs index bf86d4ac41dd..edca740cf0e7 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/impls.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/impls.rs @@ -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>>(&self, value: T) -> Option { self.tcx.lift(value) } - pub fn mk_args_from_iter(&self, iter: I) -> T::Output - where - I: Iterator, - T: ty::CollectAndApply, 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> { - self.tcx.mk_poly_existential_predicates(eps) - } - - pub fn mk_type_list(&self, v: &[Ty<'tcx>]) -> &'tcx List> { - self.tcx.mk_type_list(v) - } - - pub fn mk_bound_variable_kinds_from_iter(&self, iter: I) -> T::Output - where - I: Iterator, - T: ty::CollectAndApply>, - { - self.tcx.mk_bound_variable_kinds_from_iter(iter) - } - - pub fn mk_place_elems(&self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List> { - self.tcx.mk_place_elems(v) - } - pub fn adt_def(&self, def_id: DefId) -> AdtDef<'tcx> { self.tcx.adt_def(def_id) } diff --git a/compiler/rustc_smir/src/rustc_smir/context/mod.rs b/compiler/rustc_smir/src/rustc_smir/context/mod.rs index b31d92cdfca6..38743e5f7d37 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/mod.rs @@ -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, } 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() } } } diff --git a/compiler/rustc_smir/src/rustc_smir/context/traits.rs b/compiler/rustc_smir/src/rustc_smir/context/traits.rs index f5cd7c330b8f..19e09016cdde 100644 --- a/compiler/rustc_smir/src/rustc_smir/context/traits.rs +++ b/compiler/rustc_smir/src/rustc_smir/context/traits.rs @@ -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>; -} diff --git a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs index 54d88ddf1979..80be1f6efe03 100644 --- a/compiler/rustc_smir/src/stable_mir/compiler_interface.rs +++ b/compiler/rustc_smir/src/stable_mir/compiler_interface.rs @@ -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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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 { 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(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 } +} diff --git a/compiler/rustc_smir/src/stable_mir/convert/internal.rs b/compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs similarity index 78% rename from compiler/rustc_smir/src/stable_mir/convert/internal.rs rename to compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs index a8c5f1085285..2a71aece7a0d 100644 --- a/compiler/rustc_smir/src/stable_mir/convert/internal.rs +++ b/compiler/rustc_smir/src/stable_mir/unstable/convert/internal.rs @@ -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() } } diff --git a/compiler/rustc_smir/src/stable_mir/unstable/mod.rs b/compiler/rustc_smir/src/stable_mir/unstable/mod.rs new file mode 100644 index 000000000000..c0e7e60a2c20 --- /dev/null +++ b/compiler/rustc_smir/src/stable_mir/unstable/mod.rs @@ -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>>(self, value: T) -> Option { + TyCtxt::lift(self, value) + } + + fn mk_args_from_iter(self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply, 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> { + TyCtxt::mk_poly_existential_predicates(self, eps) + } + + fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List> { + 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(self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply>, + { + TyCtxt::mk_bound_variable_kinds_from_iter(self, iter) + } + + fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List> { + 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>>(self, value: T) -> Option; + + fn mk_args_from_iter(self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply, 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>; + + fn mk_type_list(self, v: &[Ty<'tcx>]) -> &'tcx List>; + + fn lifetimes_re_erased(self) -> ty::Region<'tcx>; + + fn mk_bound_variable_kinds_from_iter(self, iter: I) -> T::Output + where + I: Iterator, + T: ty::CollectAndApply>; + + fn mk_place_elems(self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List>; + + 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), + } +}