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 +unsafe impl<'tcx, T> RustcInternal<'tcx> for Binder where T: RustcInternal<'tcx>, T::T: rustc_ty::TypeVisitable>, { 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 +unsafe impl<'tcx, T> RustcInternal<'tcx> for Option where T: RustcInternal<'tcx>, { type T = Option; - 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 +unsafe impl<'tcx, T> RustcInternal<'tcx> for Vec where T: RustcInternal<'tcx>, { type T = Vec; - 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, } } diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index cd4ad724b00..b17ad153ed5 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -24,12 +24,38 @@ use std::ops::Index; mod internal; pub mod pretty; +/// Convert an internal Rust compiler item into its stable counterpart, if one exists. +/// +/// # Warning +/// +/// This function is unstable, and its behavior may change at any point. +/// E.g.: Items that were previously supported, may no longer be supported, or its translation may +/// change. +/// +/// # Panics +/// +/// This function will panic if StableMIR has not been properly initialized. pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T { with_tables(|tables| item.stable(tables)) } -pub fn internal<'tcx, S: RustcInternal<'tcx>>(item: S) -> S::T { - with_tables(|tables| item.internal(tables)) +/// Convert a stable item into its internal Rust compiler counterpart, if one exists. +/// +/// # Warning +/// +/// This function is unstable, and it's behavior may change at any point. +/// Not every stable item can be converted to an internal one. +/// Furthermore, items that were previously supported, may no longer be supported in newer versions. +/// +/// # Panics +/// +/// This function will panic if StableMIR has not been properly initialized. +pub fn internal<'tcx, S>(tcx: TyCtxt<'tcx>, item: S) -> S::T +where + S: RustcInternal<'tcx>, +{ + // The tcx argument ensures that the item won't outlive the type context. + with_tables(|tables| item.internal(tables, tcx)) } impl<'tcx> Index for Tables<'tcx> { @@ -393,7 +419,12 @@ impl Index { +/// +/// # Safety +/// +/// This trait is unsafe, and every implementation should ensure that their translation +/// is lifted if necessary with the given type context (`tcx`). +pub unsafe trait RustcInternal<'tcx> { type T; - fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T; + fn internal(&self, tables: &mut Tables<'tcx>, tcx: TyCtxt<'tcx>) -> Self::T; } diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs index 48cb164c308..5d02e3d6e92 100644 --- a/compiler/rustc_smir/src/rustc_smir/alloc.rs +++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs @@ -27,7 +27,8 @@ pub fn new_allocation<'tcx>( const_value: ConstValue<'tcx>, tables: &mut Tables<'tcx>, ) -> Allocation { - try_new_allocation(ty, const_value, tables).unwrap() + try_new_allocation(ty, const_value, tables) + .expect(&format!("Failed to convert: {const_value:?} to {ty:?}")) } #[allow(rustc::usage_of_qualified_ty)] diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index fffc454804d..10085f659b3 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -29,7 +29,7 @@ use stable_mir::{Crate, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, S use std::cell::RefCell; use std::iter; -use crate::rustc_internal::{internal, RustcInternal}; +use crate::rustc_internal::RustcInternal; use crate::rustc_smir::builder::BodyBuilder; use crate::rustc_smir::{alloc, new_item_kind, smir_crate, Stable, Tables}; @@ -74,9 +74,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn trait_decls(&self, crate_num: CrateNum) -> stable_mir::TraitDecls { let mut tables = self.0.borrow_mut(); - tables - .tcx - .traits(crate_num.internal(&mut *tables)) + let tcx = tables.tcx; + tcx.traits(crate_num.internal(&mut *tables, tcx)) .iter() .map(|trait_def_id| tables.trait_def(*trait_def_id)) .collect() @@ -101,9 +100,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn trait_impls(&self, crate_num: CrateNum) -> stable_mir::ImplTraitDecls { let mut tables = self.0.borrow_mut(); - tables - .tcx - .trait_impls_in_crate(crate_num.internal(&mut *tables)) + let tcx = tables.tcx; + tcx.trait_impls_in_crate(crate_num.internal(&mut *tables, tcx)) .iter() .map(|impl_def_id| tables.impl_def(*impl_def_id)) .collect() @@ -229,57 +227,68 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn adt_kind(&self, def: AdtDef) -> AdtKind { let mut tables = self.0.borrow_mut(); - def.internal(&mut *tables).adt_kind().stable(&mut *tables) + let tcx = tables.tcx; + def.internal(&mut *tables, tcx).adt_kind().stable(&mut *tables) } fn adt_is_box(&self, def: AdtDef) -> bool { let mut tables = self.0.borrow_mut(); - def.internal(&mut *tables).is_box() + let tcx = tables.tcx; + def.internal(&mut *tables, tcx).is_box() } fn adt_is_simd(&self, def: AdtDef) -> bool { let mut tables = self.0.borrow_mut(); - def.internal(&mut *tables).repr().simd() + let tcx = tables.tcx; + def.internal(&mut *tables, tcx).repr().simd() } fn adt_is_cstr(&self, def: AdtDef) -> bool { let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); + let tcx = tables.tcx; + let def_id = def.0.internal(&mut *tables, tcx); tables.tcx.lang_items().c_str() == Some(def_id) } fn fn_sig(&self, def: FnDef, args: &GenericArgs) -> PolyFnSig { let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); - let sig = tables.tcx.fn_sig(def_id).instantiate(tables.tcx, args.internal(&mut *tables)); + let tcx = tables.tcx; + let def_id = def.0.internal(&mut *tables, tcx); + let sig = + tables.tcx.fn_sig(def_id).instantiate(tables.tcx, args.internal(&mut *tables, tcx)); sig.stable(&mut *tables) } fn closure_sig(&self, args: &GenericArgs) -> PolyFnSig { let mut tables = self.0.borrow_mut(); - let args_ref = args.internal(&mut *tables); + let tcx = tables.tcx; + let args_ref = args.internal(&mut *tables, tcx); let sig = args_ref.as_closure().sig(); sig.stable(&mut *tables) } fn adt_variants_len(&self, def: AdtDef) -> usize { let mut tables = self.0.borrow_mut(); - def.internal(&mut *tables).variants().len() + let tcx = tables.tcx; + def.internal(&mut *tables, tcx).variants().len() } fn variant_name(&self, def: VariantDef) -> Symbol { let mut tables = self.0.borrow_mut(); - def.internal(&mut *tables).name.to_string() + let tcx = tables.tcx; + def.internal(&mut *tables, tcx).name.to_string() } fn variant_fields(&self, def: VariantDef) -> Vec { let mut tables = self.0.borrow_mut(); - def.internal(&mut *tables).fields.iter().map(|f| f.stable(&mut *tables)).collect() + let tcx = tables.tcx; + def.internal(&mut *tables, tcx).fields.iter().map(|f| f.stable(&mut *tables)).collect() } fn eval_target_usize(&self, cnst: &Const) -> Result { let mut tables = self.0.borrow_mut(); - let mir_const = cnst.internal(&mut *tables); + let tcx = tables.tcx; + let mir_const = cnst.internal(&mut *tables, tcx); mir_const .try_eval_target_usize(tables.tcx, ParamEnv::empty()) .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) @@ -299,30 +308,36 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn new_rigid_ty(&self, kind: RigidTy) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); - let internal_kind = kind.internal(&mut *tables); + let tcx = tables.tcx; + let internal_kind = kind.internal(&mut *tables, tcx); tables.tcx.mk_ty_from_kind(internal_kind).stable(&mut *tables) } fn new_box_ty(&self, ty: stable_mir::ty::Ty) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); - let inner = ty.internal(&mut *tables); + let tcx = tables.tcx; + let inner = ty.internal(&mut *tables, tcx); ty::Ty::new_box(tables.tcx, inner).stable(&mut *tables) } fn def_ty(&self, item: stable_mir::DefId) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); - tables.tcx.type_of(item.internal(&mut *tables)).instantiate_identity().stable(&mut *tables) + let tcx = tables.tcx; + tcx.type_of(item.internal(&mut *tables, tcx)).instantiate_identity().stable(&mut *tables) } fn def_ty_with_args(&self, item: stable_mir::DefId, args: &GenericArgs) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); - let args = args.internal(&mut *tables); - let def_ty = tables.tcx.type_of(item.internal(&mut *tables)); + let tcx = tables.tcx; + let args = args.internal(&mut *tables, tcx); + let def_ty = tables.tcx.type_of(item.internal(&mut *tables, tcx)); def_ty.instantiate(tables.tcx, args).stable(&mut *tables) } fn const_literal(&self, cnst: &stable_mir::ty::Const) -> String { - internal(cnst).to_string() + let mut tables = self.0.borrow_mut(); + let tcx = tables.tcx; + cnst.internal(&mut *tables, tcx).to_string() } fn span_of_an_item(&self, def_id: stable_mir::DefId) -> Span { @@ -337,7 +352,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); - let internal_kind = ty.internal(&mut *tables); + let tcx = tables.tcx; + let internal_kind = ty.internal(&mut *tables, tcx); let internal_ty = tables.tcx.mk_ty_from_kind(internal_kind); internal_ty.discriminant_ty(tables.tcx).stable(&mut *tables) } @@ -407,8 +423,9 @@ impl<'tcx> Context for TablesWrapper<'tcx> { args: &stable_mir::ty::GenericArgs, ) -> Option { let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); - let args_ref = args.internal(&mut *tables); + let tcx = tables.tcx; + let def_id = def.0.internal(&mut *tables, tcx); + let args_ref = args.internal(&mut *tables, tcx); match Instance::resolve(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) { Ok(Some(instance)) => Some(instance.stable(&mut *tables)), Ok(None) | Err(_) => None, @@ -417,7 +434,8 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn resolve_drop_in_place(&self, ty: stable_mir::ty::Ty) -> stable_mir::mir::mono::Instance { let mut tables = self.0.borrow_mut(); - let internal_ty = ty.internal(&mut *tables); + let tcx = tables.tcx; + let internal_ty = ty.internal(&mut *tables, tcx); let instance = Instance::resolve_drop_in_place(tables.tcx, internal_ty); instance.stable(&mut *tables) } @@ -428,8 +446,9 @@ impl<'tcx> Context for TablesWrapper<'tcx> { args: &GenericArgs, ) -> Option { let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); - let args_ref = args.internal(&mut *tables); + let tcx = tables.tcx; + let def_id = def.0.internal(&mut *tables, tcx); + let args_ref = args.internal(&mut *tables, tcx); Instance::resolve_for_fn_ptr(tables.tcx, ParamEnv::reveal_all(), def_id, args_ref) .stable(&mut *tables) } @@ -441,36 +460,44 @@ impl<'tcx> Context for TablesWrapper<'tcx> { kind: ClosureKind, ) -> Option { let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); - let args_ref = args.internal(&mut *tables); - let closure_kind = kind.internal(&mut *tables); + let tcx = tables.tcx; + let def_id = def.0.internal(&mut *tables, tcx); + let args_ref = args.internal(&mut *tables, tcx); + let closure_kind = kind.internal(&mut *tables, tcx); Instance::resolve_closure(tables.tcx, def_id, args_ref, closure_kind).stable(&mut *tables) } fn eval_instance(&self, def: InstanceDef, const_ty: Ty) -> Result { let mut tables = self.0.borrow_mut(); let instance = tables.instances[def]; - let result = tables.tcx.const_eval_instance( + let tcx = tables.tcx; + let result = tcx.const_eval_instance( ParamEnv::reveal_all(), instance, - Some(tables.tcx.def_span(instance.def_id())), + Some(tcx.def_span(instance.def_id())), ); result .map(|const_val| { - alloc::try_new_allocation(const_ty.internal(&mut *tables), const_val, &mut *tables) + alloc::try_new_allocation( + const_ty.internal(&mut *tables, tcx), + const_val, + &mut *tables, + ) }) .map_err(|e| e.stable(&mut *tables))? } fn eval_static_initializer(&self, def: StaticDef) -> Result { let mut tables = self.0.borrow_mut(); - let def_id = def.0.internal(&mut *tables); + let tcx = tables.tcx; + let def_id = def.0.internal(&mut *tables, tcx); tables.tcx.eval_static_initializer(def_id).stable(&mut *tables) } fn global_alloc(&self, alloc: stable_mir::mir::alloc::AllocId) -> GlobalAlloc { let mut tables = self.0.borrow_mut(); - let alloc_id = alloc.internal(&mut *tables); + let tcx = tables.tcx; + let alloc_id = alloc.internal(&mut *tables, tcx); tables.tcx.global_alloc(alloc_id).stable(&mut *tables) } @@ -480,9 +507,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ) -> Option { let mut tables = self.0.borrow_mut(); let GlobalAlloc::VTable(ty, trait_ref) = global_alloc else { return None }; - let alloc_id = tables - .tcx - .vtable_allocation((ty.internal(&mut *tables), trait_ref.internal(&mut *tables))); + let tcx = tables.tcx; + let alloc_id = tables.tcx.vtable_allocation(( + ty.internal(&mut *tables, tcx), + trait_ref.internal(&mut *tables, tcx), + )); Some(alloc_id.stable(&mut *tables)) } @@ -510,14 +539,16 @@ impl<'tcx> Context for TablesWrapper<'tcx> { fn ty_layout(&self, ty: Ty) -> Result { let mut tables = self.0.borrow_mut(); - let ty = ty.internal(&mut *tables); + let tcx = tables.tcx; + let ty = ty.internal(&mut *tables, tcx); let layout = tables.layout_of(ty)?.layout; Ok(layout.stable(&mut *tables)) } fn layout_shape(&self, id: Layout) -> LayoutShape { let mut tables = self.0.borrow_mut(); - id.internal(&mut *tables).0.stable(&mut *tables) + let tcx = tables.tcx; + id.internal(&mut *tables, tcx).0.stable(&mut *tables) } } diff --git a/tests/ui-fulldeps/stable-mir/smir_internal.rs b/tests/ui-fulldeps/stable-mir/smir_internal.rs index b4faaeb4fc0..e23b0f6820a 100644 --- a/tests/ui-fulldeps/stable-mir/smir_internal.rs +++ b/tests/ui-fulldeps/stable-mir/smir_internal.rs @@ -26,11 +26,11 @@ use std::ops::ControlFlow; const CRATE_NAME: &str = "input"; -fn test_translation(_tcx: TyCtxt) -> ControlFlow<()> { +fn test_translation(tcx: TyCtxt<'_>) -> ControlFlow<()> { let main_fn = stable_mir::entry_fn().unwrap(); let body = main_fn.body(); let orig_ty = body.locals()[0].ty; - let rustc_ty = rustc_internal::internal(&orig_ty); + let rustc_ty = rustc_internal::internal(tcx, &orig_ty); assert!(rustc_ty.is_unit()); ControlFlow::Continue(()) }