Lift Lift

This commit is contained in:
Michael Goulet 2024-05-10 14:27:48 -04:00
parent 6a19a87097
commit 5e606c0bde
8 changed files with 17 additions and 33 deletions

View File

@ -41,7 +41,7 @@ pub fn lift_derive(mut s: synstructure::Structure<'_>) -> proc_macro2::TokenStre
s.add_impl_generic(newtcx); s.add_impl_generic(newtcx);
s.bound_impl( s.bound_impl(
quote!(::rustc_middle::ty::Lift<'__lifted>), quote!(::rustc_middle::ty::Lift<::rustc_middle::ty::TyCtxt<'__lifted>>),
quote! { quote! {
type Lifted = #lifted; type Lifted = #lifted;

View File

@ -57,7 +57,7 @@ macro_rules! span_bug {
macro_rules! TrivialLiftImpls { macro_rules! TrivialLiftImpls {
($($ty:ty),+ $(,)?) => { ($($ty:ty),+ $(,)?) => {
$( $(
impl<'tcx> $crate::ty::Lift<'tcx> for $ty { impl<'tcx> $crate::ty::Lift<$crate::ty::TyCtxt<'tcx>> for $ty {
type Lifted = Self; type Lifted = Self;
fn lift_to_tcx(self, _: $crate::ty::TyCtxt<'tcx>) -> Option<Self> { fn lift_to_tcx(self, _: $crate::ty::TyCtxt<'tcx>) -> Option<Self> {
Some(self) Some(self)

View File

@ -4,6 +4,8 @@
pub mod tls; pub mod tls;
pub use rustc_type_ir::lift::Lift;
use crate::arena::Arena; use crate::arena::Arena;
use crate::dep_graph::{DepGraph, DepKindStruct}; use crate::dep_graph::{DepGraph, DepKindStruct};
use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos}; use crate::infer::canonical::{CanonicalParamEnvCache, CanonicalVarInfo, CanonicalVarInfos};
@ -917,7 +919,7 @@ impl<'tcx> TyCtxt<'tcx> {
) )
} }
pub fn lift<T: Lift<'tcx>>(self, value: T) -> Option<T::Lifted> { pub fn lift<T: Lift<TyCtxt<'tcx>>>(self, value: T) -> Option<T::Lifted> {
value.lift_to_tcx(self) value.lift_to_tcx(self)
} }
@ -1524,31 +1526,9 @@ impl<'tcx> TyCtxt<'tcx> {
} }
} }
/// A trait implemented for all `X<'a>` types that can be safely and
/// efficiently converted to `X<'tcx>` as long as they are part of the
/// provided `TyCtxt<'tcx>`.
/// This can be done, for example, for `Ty<'tcx>` or `GenericArgsRef<'tcx>`
/// by looking them up in their respective interners.
///
/// However, this is still not the best implementation as it does
/// need to compare the components, even for interned values.
/// It would be more efficient if `TypedArena` provided a way to
/// determine whether the address is in the allocated range.
///
/// `None` is returned if the value or one of the components is not part
/// of the provided context.
/// For `Ty`, `None` can be returned if either the type interner doesn't
/// contain the `TyKind` key or if the address of the interned
/// pointer differs. The latter case is possible if a primitive type,
/// e.g., `()` or `u8`, was interned in a different context.
pub trait Lift<'tcx>: fmt::Debug {
type Lifted: fmt::Debug + 'tcx;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted>;
}
macro_rules! nop_lift { macro_rules! nop_lift {
($set:ident; $ty:ty => $lifted:ty) => { ($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for $ty { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for $ty {
type Lifted = $lifted; type Lifted = $lifted;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
// Assert that the set has the right type. // Assert that the set has the right type.
@ -1583,7 +1563,7 @@ macro_rules! nop_lift {
macro_rules! nop_list_lift { macro_rules! nop_list_lift {
($set:ident; $ty:ty => $lifted:ty) => { ($set:ident; $ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for &'a List<$ty> { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a List<$ty> {
type Lifted = &'tcx List<$lifted>; type Lifted = &'tcx List<$lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
// Assert that the set has the right type. // Assert that the set has the right type.
@ -1621,7 +1601,7 @@ nop_list_lift! {args; GenericArg<'a> => GenericArg<'tcx>}
macro_rules! nop_slice_lift { macro_rules! nop_slice_lift {
($ty:ty => $lifted:ty) => { ($ty:ty => $lifted:ty) => {
impl<'a, 'tcx> Lift<'tcx> for &'a [$ty] { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for &'a [$ty] {
type Lifted = &'tcx [$lifted]; type Lifted = &'tcx [$lifted];
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
if self.is_empty() { if self.is_empty() {

View File

@ -205,7 +205,7 @@ impl<'tcx> GenericArg<'tcx> {
} }
} }
impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for GenericArg<'a> {
type Lifted = GenericArg<'tcx>; type Lifted = GenericArg<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {

View File

@ -478,7 +478,7 @@ TrivialTypeTraversalAndLiftImpls! {
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// Lift implementations // Lift implementations
impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> { impl<'tcx, T: Lift<TyCtxt<'tcx>>> Lift<TyCtxt<'tcx>> for Option<T> {
type Lifted = Option<T::Lifted>; type Lifted = Option<T::Lifted>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
Some(match self { Some(match self {
@ -488,7 +488,7 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for Option<T> {
} }
} }
impl<'a, 'tcx> Lift<'tcx> for Term<'a> { impl<'a, 'tcx> Lift<TyCtxt<'tcx>> for Term<'a> {
type Lifted = ty::Term<'tcx>; type Lifted = ty::Term<'tcx>;
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> { fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
Some( Some(

View File

@ -34,7 +34,9 @@ where
} }
} }
pub trait Normalizable<'tcx>: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx> + Copy { pub trait Normalizable<'tcx>:
fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<TyCtxt<'tcx>> + Copy
{
fn type_op_method( fn type_op_method(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>, canonicalized: Canonical<'tcx, ParamEnvAnd<'tcx, Normalize<Self>>>,

View File

@ -54,7 +54,7 @@ fn type_op_normalize<'tcx, T>(
key: ParamEnvAnd<'tcx, Normalize<T>>, key: ParamEnvAnd<'tcx, Normalize<T>>,
) -> Result<T, NoSolution> ) -> Result<T, NoSolution>
where where
T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>> + Lift<'tcx>, T: fmt::Debug + TypeFoldable<TyCtxt<'tcx>>,
{ {
let (param_env, Normalize { value }) = key.into_parts(); let (param_env, Normalize { value }) = key.into_parts();
let Normalized { value, obligations } = let Normalized { value, obligations } =

View File

@ -26,6 +26,7 @@ pub mod fold;
pub mod new; pub mod new;
pub mod ty_info; pub mod ty_info;
pub mod ty_kind; pub mod ty_kind;
pub mod lift;
#[macro_use] #[macro_use]
mod macros; mod macros;
@ -57,6 +58,7 @@ pub use DynKind::*;
pub use InferTy::*; pub use InferTy::*;
pub use RegionKind::*; pub use RegionKind::*;
pub use TyKind::*; pub use TyKind::*;
pub use lift::*;
rustc_index::newtype_index! { rustc_index::newtype_index! {
/// A [De Bruijn index][dbi] is a standard means of representing /// A [De Bruijn index][dbi] is a standard means of representing