about summary refs log tree commit diff
path: root/compiler/rustc_smir/src/rustc_internal/internal.rs
diff options
context:
space:
mode:
authorCelina G. Val <celinval@amazon.com>2024-01-17 18:35:19 -0800
committerOli Scherer <git-spam-no-reply9815368754983@oli-obk.de>2024-01-19 10:00:32 +0000
commit9aace6723572438a94378451793ca37deb768e72 (patch)
tree63583d45cf50a8ba4fd24d220fd40b26dac57a25 /compiler/rustc_smir/src/rustc_internal/internal.rs
parent61361c16aac632367c0137ce74f6d3248edd8932 (diff)
downloadrust-9aace6723572438a94378451793ca37deb768e72.tar.gz
rust-9aace6723572438a94378451793ca37deb768e72.zip
Ensure internal function is safe
The internal function was unsound, it could cause UB in rare cases where
the user inadvertly stored the returned object in a location that could
outlive the TyCtxt.

In order to make it safe, we now take a type context as an argument to
the internal fn, and we ensure that interned items are lifted using the
provided context.

Thus, this change ensures that the compiler can properly enforce
that the object does not outlive the type context it was lifted to.
Diffstat (limited to 'compiler/rustc_smir/src/rustc_internal/internal.rs')
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs333
1 files changed, 183 insertions, 150 deletions
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index 5689e8f3b3d..01260659fd5 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -5,7 +5,7 @@
 
 // Prefer importing stable_mir over internal rustc constructs to make this file more readable.
 use crate::rustc_smir::Tables;
-use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy};
+use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy, TyCtxt};
 use rustc_span::Symbol;
 use stable_mir::abi::Layout;
 use stable_mir::mir::alloc::AllocId;
@@ -21,118 +21,120 @@ use stable_mir::{CrateItem, CrateNum, DefId};
 
 use super::RustcInternal;
 
-impl<'tcx> RustcInternal<'tcx> for CrateItem {
+unsafe impl<'tcx> RustcInternal<'tcx> for CrateItem {
     type T = rustc_span::def_id::DefId;
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        self.0.internal(tables)
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        self.0.internal(tables, tcx)
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for CrateNum {
+unsafe impl<'tcx> RustcInternal<'tcx> for CrateNum {
     type T = rustc_span::def_id::CrateNum;
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         rustc_span::def_id::CrateNum::from_usize(*self)
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for DefId {
+unsafe impl<'tcx> RustcInternal<'tcx> for DefId {
     type T = rustc_span::def_id::DefId;
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        tables.def_ids[*self]
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        tcx.lift(tables.def_ids[*self]).unwrap()
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for GenericArgs {
+unsafe impl<'tcx> RustcInternal<'tcx> for GenericArgs {
     type T = rustc_ty::GenericArgsRef<'tcx>;
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        tables.tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables)))
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        tcx.mk_args_from_iter(self.0.iter().map(|arg| arg.internal(tables, tcx)))
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
+unsafe impl<'tcx> RustcInternal<'tcx> for GenericArgKind {
     type T = rustc_ty::GenericArg<'tcx>;
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        match self {
-            GenericArgKind::Lifetime(reg) => reg.internal(tables).into(),
-            GenericArgKind::Type(ty) => ty.internal(tables).into(),
-            GenericArgKind::Const(cnst) => ty_const(cnst, tables).into(),
-        }
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        let arg: rustc_ty::GenericArg<'tcx> = match self {
+            GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(),
+            GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(),
+            GenericArgKind::Const(cnst) => ty_const(cnst, tables, tcx).into(),
+        };
+        tcx.lift(arg).unwrap()
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Region {
+unsafe impl<'tcx> RustcInternal<'tcx> for Region {
     type T = rustc_ty::Region<'tcx>;
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        // Cannot recover region. Use erased instead.
-        tables.tcx.lifetimes.re_erased
+    fn internal(&self, _tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        // Cannot recover region. Use erased for now.
+        tcx.lifetimes.re_erased
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Ty {
+unsafe impl<'tcx> RustcInternal<'tcx> for Ty {
     type T = InternalTy<'tcx>;
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        tables.types[*self]
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        tcx.lift(tables.types[*self]).unwrap()
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for RigidTy {
+unsafe impl<'tcx> RustcInternal<'tcx> for RigidTy {
     type T = rustc_ty::TyKind<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
         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)),
-            RigidTy::Uint(uint_ty) => rustc_ty::TyKind::Uint(uint_ty.internal(tables)),
-            RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables)),
+            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), ty_const(cnst, tables))
+                rustc_ty::TyKind::Array(ty.internal(tables, tcx), ty_const(cnst, tables, tcx))
             }
             RigidTy::Adt(def, args) => {
-                rustc_ty::TyKind::Adt(def.internal(tables), args.internal(tables))
+                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)),
+            RigidTy::Slice(ty) => rustc_ty::TyKind::Slice(ty.internal(tables, tcx)),
             RigidTy::RawPtr(ty, mutability) => rustc_ty::TyKind::RawPtr(rustc_ty::TypeAndMut {
-                ty: ty.internal(tables),
-                mutbl: mutability.internal(tables),
+                ty: ty.internal(tables, tcx),
+                mutbl: mutability.internal(tables, tcx),
             }),
             RigidTy::Ref(region, ty, mutability) => rustc_ty::TyKind::Ref(
-                region.internal(tables),
-                ty.internal(tables),
-                mutability.internal(tables),
+                region.internal(tables, tcx),
+                ty.internal(tables, tcx),
+                mutability.internal(tables, tcx),
             ),
-            RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables)),
+            RigidTy::Foreign(def) => rustc_ty::TyKind::Foreign(def.0.internal(tables, tcx)),
             RigidTy::FnDef(def, args) => {
-                rustc_ty::TyKind::FnDef(def.0.internal(tables), args.internal(tables))
+                rustc_ty::TyKind::FnDef(def.0.internal(tables, tcx), args.internal(tables, tcx))
             }
-            RigidTy::FnPtr(sig) => rustc_ty::TyKind::FnPtr(sig.internal(tables)),
+            RigidTy::FnPtr(sig) => rustc_ty::TyKind::FnPtr(sig.internal(tables, tcx)),
             RigidTy::Closure(def, args) => {
-                rustc_ty::TyKind::Closure(def.0.internal(tables), args.internal(tables))
+                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), args.internal(tables))
-            }
-            RigidTy::CoroutineWitness(def, args) => {
-                rustc_ty::TyKind::CoroutineWitness(def.0.internal(tables), args.internal(tables))
+                rustc_ty::TyKind::Coroutine(def.0.internal(tables, tcx), args.internal(tables, tcx))
             }
+            RigidTy::CoroutineWitness(def, args) => rustc_ty::TyKind::CoroutineWitness(
+                def.0.internal(tables, tcx),
+                args.internal(tables, tcx),
+            ),
             RigidTy::Dynamic(predicate, region, dyn_kind) => rustc_ty::TyKind::Dynamic(
-                tables.tcx.mk_poly_existential_predicates(&predicate.internal(tables)),
-                region.internal(tables),
-                dyn_kind.internal(tables),
+                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(tables.tcx.mk_type_list(&tys.internal(tables)))
+                rustc_ty::TyKind::Tuple(tcx.mk_type_list(&tys.internal(tables, tcx)))
             }
         }
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for IntTy {
+unsafe impl<'tcx> RustcInternal<'tcx> for IntTy {
     type T = rustc_ty::IntTy;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
             IntTy::Isize => rustc_ty::IntTy::Isize,
             IntTy::I8 => rustc_ty::IntTy::I8,
@@ -144,10 +146,10 @@ impl<'tcx> RustcInternal<'tcx> for IntTy {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for UintTy {
+unsafe impl<'tcx> RustcInternal<'tcx> for UintTy {
     type T = rustc_ty::UintTy;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
             UintTy::Usize => rustc_ty::UintTy::Usize,
             UintTy::U8 => rustc_ty::UintTy::U8,
@@ -159,10 +161,10 @@ impl<'tcx> RustcInternal<'tcx> for UintTy {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for FloatTy {
+unsafe impl<'tcx> RustcInternal<'tcx> for FloatTy {
     type T = rustc_ty::FloatTy;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
             FloatTy::F32 => rustc_ty::FloatTy::F32,
             FloatTy::F64 => rustc_ty::FloatTy::F64,
@@ -170,10 +172,10 @@ impl<'tcx> RustcInternal<'tcx> for FloatTy {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Mutability {
+unsafe impl<'tcx> RustcInternal<'tcx> for Mutability {
     type T = rustc_ty::Mutability;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
             Mutability::Not => rustc_ty::Mutability::Not,
             Mutability::Mut => rustc_ty::Mutability::Mut,
@@ -181,10 +183,10 @@ impl<'tcx> RustcInternal<'tcx> for Mutability {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Movability {
+unsafe impl<'tcx> RustcInternal<'tcx> for Movability {
     type T = rustc_ty::Movability;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
             Movability::Static => rustc_ty::Movability::Static,
             Movability::Movable => rustc_ty::Movability::Movable,
@@ -192,37 +194,44 @@ impl<'tcx> RustcInternal<'tcx> for Movability {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for FnSig {
+unsafe impl<'tcx> RustcInternal<'tcx> for FnSig {
     type T = rustc_ty::FnSig<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        rustc_ty::FnSig {
-            inputs_and_output: tables.tcx.mk_type_list(&self.inputs_and_output.internal(tables)),
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        tcx.lift(rustc_ty::FnSig {
+            inputs_and_output: tables
+                .tcx
+                .mk_type_list(&self.inputs_and_output.internal(tables, tcx)),
             c_variadic: self.c_variadic,
-            unsafety: self.unsafety.internal(tables),
-            abi: self.abi.internal(tables),
-        }
+            unsafety: self.unsafety.internal(tables, tcx),
+            abi: self.abi.internal(tables, tcx),
+        })
+        .unwrap()
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for VariantIdx {
+unsafe impl<'tcx> RustcInternal<'tcx> for VariantIdx {
     type T = rustc_target::abi::VariantIdx;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         rustc_target::abi::VariantIdx::from(self.to_index())
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for VariantDef {
+unsafe impl<'tcx> RustcInternal<'tcx> for VariantDef {
     type T = &'tcx rustc_ty::VariantDef;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        self.adt_def.internal(tables).variant(self.idx.internal(tables))
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        self.adt_def.internal(tables, tcx).variant(self.idx.internal(tables, tcx))
     }
 }
 
-fn ty_const<'tcx>(constant: &Const, tables: &mut Tables<'tcx>) -> rustc_ty::Const<'tcx> {
-    match constant.internal(tables) {
+fn ty_const<'tcx>(
+    constant: &Const,
+    tables: &mut Tables<'tcx>,
+    tcx: TyCtxt<'tcx>,
+) -> rustc_ty::Const<'tcx> {
+    match constant.internal(tables, tcx) {
         rustc_middle::mir::Const::Ty(c) => c,
         cnst => {
             panic!("Trying to convert constant `{constant:?}` to type constant, but found {cnst:?}")
@@ -230,21 +239,33 @@ fn ty_const<'tcx>(constant: &Const, tables: &mut Tables<'tcx>) -> rustc_ty::Cons
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Const {
+unsafe impl<'tcx> RustcInternal<'tcx> for Const {
     type T = rustc_middle::mir::Const<'tcx>;
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        tables.constants[self.id]
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        let constant = tables.constants[self.id];
+        match constant {
+            rustc_middle::mir::Const::Ty(ty) => rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap()),
+            rustc_middle::mir::Const::Unevaluated(uneval, ty) => {
+                rustc_middle::mir::Const::Unevaluated(
+                    lift_unevaluated(tcx, uneval),
+                    tcx.lift(ty).unwrap(),
+                )
+            }
+            rustc_middle::mir::Const::Val(const_val, ty) => {
+                rustc_middle::mir::Const::Val(tcx.lift(const_val).unwrap(), tcx.lift(ty).unwrap())
+            }
+        }
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for MonoItem {
+unsafe impl<'tcx> RustcInternal<'tcx> for MonoItem {
     type T = rustc_middle::mir::mono::MonoItem<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
         use rustc_middle::mir::mono as rustc_mono;
         match self {
-            MonoItem::Fn(instance) => rustc_mono::MonoItem::Fn(instance.internal(tables)),
-            MonoItem::Static(def) => rustc_mono::MonoItem::Static(def.internal(tables)),
+            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!()
             }
@@ -252,55 +273,56 @@ impl<'tcx> RustcInternal<'tcx> for MonoItem {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Instance {
+unsafe impl<'tcx> RustcInternal<'tcx> for Instance {
     type T = rustc_ty::Instance<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        tables.instances[self.def]
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        tcx.lift(tables.instances[self.def]).unwrap()
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for StaticDef {
+unsafe impl<'tcx> RustcInternal<'tcx> for StaticDef {
     type T = rustc_span::def_id::DefId;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        self.0.internal(tables)
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        self.0.internal(tables, tcx)
     }
 }
 
 #[allow(rustc::usage_of_qualified_ty)]
-impl<'tcx, T> RustcInternal<'tcx> for Binder<T>
+unsafe impl<'tcx, T> RustcInternal<'tcx> for Binder<T>
 where
     T: RustcInternal<'tcx>,
     T::T: rustc_ty::TypeVisitable<rustc_ty::TyCtxt<'tcx>>,
 {
     type T = rustc_ty::Binder<'tcx, T::T>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
         rustc_ty::Binder::bind_with_vars(
-            self.value.internal(tables),
-            tables.tcx.mk_bound_variable_kinds_from_iter(
-                self.bound_vars.iter().map(|bound| bound.internal(tables)),
+            self.value.internal(tables, tcx),
+            tcx.mk_bound_variable_kinds_from_iter(
+                self.bound_vars.iter().map(|bound| bound.internal(tables, tcx)),
             ),
         )
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for BoundVariableKind {
+unsafe impl<'tcx> RustcInternal<'tcx> for BoundVariableKind {
     type T = rustc_ty::BoundVariableKind;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
         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), Symbol::intern(symbol))
-                }
+                BoundTyKind::Param(def, 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::BrAnon,
                 BoundRegionKind::BrNamed(def, symbol) => rustc_ty::BoundRegionKind::BrNamed(
-                    def.0.internal(tables),
+                    def.0.internal(tables, tcx),
                     Symbol::intern(symbol),
                 ),
                 BoundRegionKind::BrEnv => rustc_ty::BoundRegionKind::BrEnv,
@@ -310,10 +332,10 @@ impl<'tcx> RustcInternal<'tcx> for BoundVariableKind {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for DynKind {
+unsafe impl<'tcx> RustcInternal<'tcx> for DynKind {
     type T = rustc_ty::DynKind;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
             DynKind::Dyn => rustc_ty::DynKind::Dyn,
             DynKind::DynStar => rustc_ty::DynKind::DynStar,
@@ -321,81 +343,81 @@ impl<'tcx> RustcInternal<'tcx> for DynKind {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for ExistentialPredicate {
+unsafe impl<'tcx> RustcInternal<'tcx> for ExistentialPredicate {
     type T = rustc_ty::ExistentialPredicate<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
             ExistentialPredicate::Trait(trait_ref) => {
-                rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables))
+                rustc_ty::ExistentialPredicate::Trait(trait_ref.internal(tables, tcx))
             }
             ExistentialPredicate::Projection(proj) => {
-                rustc_ty::ExistentialPredicate::Projection(proj.internal(tables))
+                rustc_ty::ExistentialPredicate::Projection(proj.internal(tables, tcx))
             }
             ExistentialPredicate::AutoTrait(trait_def) => {
-                rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables))
+                rustc_ty::ExistentialPredicate::AutoTrait(trait_def.0.internal(tables, tcx))
             }
         }
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for ExistentialProjection {
+unsafe impl<'tcx> RustcInternal<'tcx> for ExistentialProjection {
     type T = rustc_ty::ExistentialProjection<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
         rustc_ty::ExistentialProjection {
-            def_id: self.def_id.0.internal(tables),
-            args: self.generic_args.internal(tables),
-            term: self.term.internal(tables),
+            def_id: self.def_id.0.internal(tables, tcx),
+            args: self.generic_args.internal(tables, tcx),
+            term: self.term.internal(tables, tcx),
         }
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for TermKind {
+unsafe impl<'tcx> RustcInternal<'tcx> for TermKind {
     type T = rustc_ty::Term<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
-            TermKind::Type(ty) => ty.internal(tables).into(),
-            TermKind::Const(const_) => ty_const(const_, tables).into(),
+            TermKind::Type(ty) => ty.internal(tables, tcx).into(),
+            TermKind::Const(const_) => ty_const(const_, tables, tcx).into(),
         }
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for ExistentialTraitRef {
+unsafe impl<'tcx> RustcInternal<'tcx> for ExistentialTraitRef {
     type T = rustc_ty::ExistentialTraitRef<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
         rustc_ty::ExistentialTraitRef {
-            def_id: self.def_id.0.internal(tables),
-            args: self.generic_args.internal(tables),
+            def_id: self.def_id.0.internal(tables, tcx),
+            args: self.generic_args.internal(tables, tcx),
         }
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for TraitRef {
+unsafe impl<'tcx> RustcInternal<'tcx> for TraitRef {
     type T = rustc_ty::TraitRef<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
         rustc_ty::TraitRef::new(
-            tables.tcx,
-            self.def_id.0.internal(tables),
-            self.args().internal(tables),
+            tcx,
+            self.def_id.0.internal(tables, tcx),
+            self.args().internal(tables, tcx),
         )
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for AllocId {
+unsafe impl<'tcx> RustcInternal<'tcx> for AllocId {
     type T = rustc_middle::mir::interpret::AllocId;
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        tables.alloc_ids[*self]
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        tcx.lift(tables.alloc_ids[*self]).unwrap()
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for ClosureKind {
+unsafe impl<'tcx> RustcInternal<'tcx> for ClosureKind {
     type T = rustc_ty::ClosureKind;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
             ClosureKind::Fn => rustc_ty::ClosureKind::Fn,
             ClosureKind::FnMut => rustc_ty::ClosureKind::FnMut,
@@ -404,17 +426,17 @@ impl<'tcx> RustcInternal<'tcx> for ClosureKind {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for AdtDef {
+unsafe impl<'tcx> RustcInternal<'tcx> for AdtDef {
     type T = rustc_ty::AdtDef<'tcx>;
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        tables.tcx.adt_def(self.0.internal(&mut *tables))
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        tcx.adt_def(self.0.internal(tables, tcx))
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Abi {
+unsafe impl<'tcx> RustcInternal<'tcx> for Abi {
     type T = rustc_target::spec::abi::Abi;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         match *self {
             Abi::Rust => rustc_target::spec::abi::Abi::Rust,
             Abi::C { unwind } => rustc_target::spec::abi::Abi::C { unwind },
@@ -447,10 +469,10 @@ impl<'tcx> RustcInternal<'tcx> for Abi {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Safety {
+unsafe impl<'tcx> RustcInternal<'tcx> for Safety {
     type T = rustc_hir::Unsafety;
 
-    fn internal(&self, _tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, _tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         match self {
             Safety::Unsafe => rustc_hir::Unsafety::Unsafe,
             Safety::Normal => rustc_hir::Unsafety::Normal,
@@ -458,51 +480,62 @@ impl<'tcx> RustcInternal<'tcx> for Safety {
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Span {
+unsafe impl<'tcx> RustcInternal<'tcx> for Span {
     type T = rustc_span::Span;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
+    fn internal(&self, tables: &mut Tables<'tcx>, _tcx: TyCtxt<'tcx>) -> Self::T {
         tables[*self]
     }
 }
 
-impl<'tcx> RustcInternal<'tcx> for Layout {
+unsafe impl<'tcx> RustcInternal<'tcx> for Layout {
     type T = rustc_target::abi::Layout<'tcx>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        tables.layouts[*self]
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        tcx.lift(tables.layouts[*self]).unwrap()
     }
 }
 
-impl<'tcx, T> RustcInternal<'tcx> for &T
+unsafe impl<'tcx, T> RustcInternal<'tcx> for &T
 where
     T: RustcInternal<'tcx>,
 {
     type T = T::T;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        (*self).internal(tables)
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        (*self).internal(tables, tcx)
     }
 }
 
-impl<'tcx, T> RustcInternal<'tcx> for Option<T>
+unsafe impl<'tcx, T> RustcInternal<'tcx> for Option<T>
 where
     T: RustcInternal<'tcx>,
 {
     type T = Option<T::T>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        self.as_ref().map(|inner| inner.internal(tables))
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        self.as_ref().map(|inner| inner.internal(tables, tcx))
     }
 }
 
-impl<'tcx, T> RustcInternal<'tcx> for Vec<T>
+unsafe impl<'tcx, T> RustcInternal<'tcx> for Vec<T>
 where
     T: RustcInternal<'tcx>,
 {
     type T = Vec<T::T>;
 
-    fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T {
-        self.iter().map(|e| e.internal(tables)).collect()
+    fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T {
+        self.iter().map(|e| e.internal(tables, tcx)).collect()
+    }
+}
+
+fn lift_unevaluated<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    uneval: rustc_middle::mir::UnevaluatedConst<'tcx>,
+) -> rustc_middle::mir::UnevaluatedConst<'tcx> {
+    rustc_middle::mir::UnevaluatedConst {
+        def: uneval.def,
+        args: tcx.lift(uneval.args).unwrap(),
+        promoted: uneval.promoted,
     }
 }