Skip to content

Commit 66d471c

Browse files
committed
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`.
1 parent 109e74a commit 66d471c

File tree

8 files changed

+420
-288
lines changed

8 files changed

+420
-288
lines changed

compiler/rustc_smir/src/rustc_internal/mod.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@ pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
4343
/// # Panics
4444
///
4545
/// This function will panic if StableMIR has not been properly initialized.
46-
pub fn internal<'tcx, S>(item: S) -> S::T<'tcx>
46+
pub fn internal<'tcx, S>(tcx: TyCtxt<'tcx>, item: S) -> S::T<'tcx>
4747
where
4848
S: RustcInternal,
4949
{
50-
with_container(|tables, cx| item.internal(tables, cx))
50+
// The tcx argument ensures that the item won't outlive the type context.
51+
// See https://github.com/rust-lang/rust/pull/120128/commits/9aace6723572438a94378451793ca37deb768e72
52+
// for more details.
53+
with_container(|tables, _| item.internal(tables, tcx))
5154
}
5255

5356
pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
@@ -69,14 +72,14 @@ where
6972

7073
/// Loads the current context and calls a function with it.
7174
/// Do not nest these, as that will ICE.
72-
pub(crate) fn with_container<'tcx, R, B: Bridge>(
73-
f: impl FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R,
75+
pub(crate) fn with_container<R, B: Bridge>(
76+
f: impl for<'tcx> FnOnce(&mut Tables<'tcx, B>, &SmirCtxt<'tcx, B>) -> R,
7477
) -> R {
7578
assert!(TLV.is_set());
7679
TLV.with(|tlv| {
7780
let ptr = tlv.get();
7881
assert!(!ptr.is_null());
79-
let container = ptr as *const SmirContainer<'tcx, B>;
82+
let container = ptr as *const SmirContainer<'_, B>;
8083
let mut tables = unsafe { (*container).tables.borrow_mut() };
8184
let cx = unsafe { (*container).cx.borrow() };
8285
f(&mut *tables, &*cx)

compiler/rustc_smir/src/rustc_smir/alloc.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ pub fn try_new_slice<'tcx, B: Bridge>(
4343
) -> Result<Allocation, B::Error> {
4444
let alloc_id = cx.tcx.reserve_and_set_memory_alloc(data);
4545
let ptr = Pointer::new(alloc_id.into(), Size::ZERO);
46-
let scalar_ptr = Scalar::from_pointer(ptr, &tables.tcx);
47-
let scalar_meta: Scalar = Scalar::from_target_usize(meta, &tables.tcx);
46+
let scalar_ptr = Scalar::from_pointer(ptr, &cx.tcx);
47+
let scalar_meta: Scalar = Scalar::from_target_usize(meta, &cx.tcx);
4848
let mut allocation = Allocation::new(layout.size, layout.align.abi, AllocInit::Uninit, ());
4949
allocation
5050
.write_scalar(&cx.tcx, alloc_range(Size::ZERO, cx.tcx.data_layout.pointer_size), scalar_ptr)

compiler/rustc_smir/src/rustc_smir/context/impls.rs

Lines changed: 1 addition & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -25,44 +25,10 @@ use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
2525
use rustc_span::{FileNameDisplayPreference, Span, Symbol};
2626
use rustc_target::callconv::FnAbi;
2727

28-
use super::{
29-
SmirAllocRange, SmirCtxt, SmirExistentialProjection, SmirExistentialTraitRef, SmirRegion,
30-
SmirTraitRef, SmirTy, SmirTypingEnv,
31-
};
28+
use super::{SmirAllocRange, SmirCtxt, SmirTy, SmirTypingEnv};
3229
use crate::rustc_smir::builder::BodyBuilder;
3330
use crate::rustc_smir::{Bridge, SmirError, Tables, filter_def_ids};
3431

35-
impl<'tcx, B: Bridge> SmirExistentialProjection<'tcx> for SmirCtxt<'tcx, B> {
36-
fn new_from_args(
37-
&self,
38-
def_id: rustc_span::def_id::DefId,
39-
args: ty::GenericArgsRef<'tcx>,
40-
term: ty::Term<'tcx>,
41-
) -> ty::ExistentialProjection<'tcx> {
42-
ty::ExistentialProjection::new_from_args(self.tcx, def_id, args, term)
43-
}
44-
}
45-
46-
impl<'tcx, B: Bridge> SmirExistentialTraitRef<'tcx> for SmirCtxt<'tcx, B> {
47-
fn new_from_args(
48-
&self,
49-
trait_def_id: DefId,
50-
args: ty::GenericArgsRef<'tcx>,
51-
) -> ty::ExistentialTraitRef<'tcx> {
52-
ty::ExistentialTraitRef::new_from_args(self.tcx, trait_def_id, args)
53-
}
54-
}
55-
56-
impl<'tcx, B: Bridge> SmirTraitRef<'tcx> for SmirCtxt<'tcx, B> {
57-
fn new_from_args(
58-
&self,
59-
trait_def_id: DefId,
60-
args: ty::GenericArgsRef<'tcx>,
61-
) -> ty::TraitRef<'tcx> {
62-
ty::TraitRef::new_from_args(self.tcx, trait_def_id, args)
63-
}
64-
}
65-
6632
impl<'tcx, B: Bridge> SmirTy<'tcx> for SmirCtxt<'tcx, B> {
6733
fn new_foreign(&self, def_id: DefId) -> ty::Ty<'tcx> {
6834
ty::Ty::new_foreign(self.tcx, def_id)
@@ -85,52 +51,11 @@ impl<'tcx, B: Bridge> SmirAllocRange<'tcx> for SmirCtxt<'tcx, B> {
8551
}
8652
}
8753

88-
impl<'tcx, B: Bridge> SmirRegion<'tcx> for SmirCtxt<'tcx, B> {
89-
fn lifetimes_re_erased(&self) -> ty::Region<'tcx> {
90-
self.tcx.lifetimes.re_erased
91-
}
92-
}
93-
9454
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
9555
pub fn lift<T: ty::Lift<TyCtxt<'tcx>>>(&self, value: T) -> Option<T::Lifted> {
9656
self.tcx.lift(value)
9757
}
9858

99-
pub fn mk_args_from_iter<I, T>(&self, iter: I) -> T::Output
100-
where
101-
I: Iterator<Item = T>,
102-
T: ty::CollectAndApply<ty::GenericArg<'tcx>, ty::GenericArgsRef<'tcx>>,
103-
{
104-
self.tcx.mk_args_from_iter(iter)
105-
}
106-
107-
pub fn mk_pat(&self, v: ty::PatternKind<'tcx>) -> ty::Pattern<'tcx> {
108-
self.tcx.mk_pat(v)
109-
}
110-
111-
pub fn mk_poly_existential_predicates(
112-
&self,
113-
eps: &[ty::PolyExistentialPredicate<'tcx>],
114-
) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
115-
self.tcx.mk_poly_existential_predicates(eps)
116-
}
117-
118-
pub fn mk_type_list(&self, v: &[Ty<'tcx>]) -> &'tcx List<Ty<'tcx>> {
119-
self.tcx.mk_type_list(v)
120-
}
121-
122-
pub fn mk_bound_variable_kinds_from_iter<I, T>(&self, iter: I) -> T::Output
123-
where
124-
I: Iterator<Item = T>,
125-
T: ty::CollectAndApply<ty::BoundVariableKind, &'tcx List<ty::BoundVariableKind>>,
126-
{
127-
self.tcx.mk_bound_variable_kinds_from_iter(iter)
128-
}
129-
130-
pub fn mk_place_elems(&self, v: &[mir::PlaceElem<'tcx>]) -> &'tcx List<mir::PlaceElem<'tcx>> {
131-
self.tcx.mk_place_elems(v)
132-
}
133-
13459
pub fn adt_def(&self, def_id: DefId) -> AdtDef<'tcx> {
13560
self.tcx.adt_def(def_id)
13661
}

compiler/rustc_smir/src/rustc_smir/context/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ pub use traits::*;
2121
/// The [`crate::stable_mir::compiler_interface::SmirInterface`] must go through
2222
/// this context to obtain rustc-level information.
2323
pub struct SmirCtxt<'tcx, B: Bridge> {
24-
pub(crate) tcx: TyCtxt<'tcx>,
24+
pub tcx: TyCtxt<'tcx>,
2525
_marker: PhantomData<B>,
2626
}
2727

2828
impl<'tcx, B: Bridge> SmirCtxt<'tcx, B> {
29-
pub(crate) fn new(tcx: TyCtxt<'tcx>) -> Self {
29+
pub fn new(tcx: TyCtxt<'tcx>) -> Self {
3030
Self { tcx, _marker: Default::default() }
3131
}
3232
}

compiler/rustc_smir/src/rustc_smir/context/traits.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,3 @@ pub trait SmirTypingEnv<'tcx> {
4444
pub trait SmirAllocRange<'tcx> {
4545
fn alloc_range(&self, offset: rustc_abi::Size, size: rustc_abi::Size) -> AllocRange;
4646
}
47-
48-
pub trait SmirRegion<'tcx> {
49-
fn lifetimes_re_erased(&self) -> ty::Region<'tcx>;
50-
}

0 commit comments

Comments
 (0)