diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:41 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:41 +0000 |
commit | 4f9fe856a25ab29345b90e7725509e9ee38a37be (patch) | |
tree | e4ffd8a9374cae7b21f7cbfb352927e0e074aff6 /compiler/rustc_middle/src/ty/subst.rs | |
parent | Adding upstream version 1.68.2+dfsg1. (diff) | |
download | rustc-4f9fe856a25ab29345b90e7725509e9ee38a37be.tar.xz rustc-4f9fe856a25ab29345b90e7725509e9ee38a37be.zip |
Adding upstream version 1.69.0+dfsg1.upstream/1.69.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | compiler/rustc_middle/src/ty/subst.rs | 100 |
1 files changed, 58 insertions, 42 deletions
diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index a07582fc8..b090bd9d8 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -3,7 +3,7 @@ use crate::ty::codec::{TyDecoder, TyEncoder}; use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder, TypeSuperFoldable}; use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts}; -use crate::ty::visit::{TypeVisitable, TypeVisitor}; +use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor}; use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt}; use rustc_data_structures::intern::Interned; @@ -71,7 +71,7 @@ impl<'tcx> List<Ty<'tcx>> { /// Allows to freely switch between `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>`. /// /// As lists are interned, `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>` have - /// be interned together, see `intern_type_list` for more details. + /// be interned together, see `mk_type_list` for more details. #[inline] pub fn as_substs(&'tcx self) -> SubstsRef<'tcx> { assert_eq!(TYPE_TAG, 0); @@ -227,8 +227,11 @@ impl<'a, 'tcx> Lift<'tcx> for GenericArg<'a> { } } -impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for GenericArg<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { match self.unpack() { GenericArgKind::Lifetime(lt) => lt.try_fold_with(folder).map(Into::into), GenericArgKind::Type(ty) => ty.try_fold_with(folder).map(Into::into), @@ -237,8 +240,8 @@ impl<'tcx> TypeFoldable<'tcx> for GenericArg<'tcx> { } } -impl<'tcx> TypeVisitable<'tcx> for GenericArg<'tcx> { - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { +impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for GenericArg<'tcx> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { match self.unpack() { GenericArgKind::Lifetime(lt) => lt.visit_with(visitor), GenericArgKind::Type(ty) => ty.visit_with(visitor), @@ -267,13 +270,11 @@ pub type SubstsRef<'tcx> = &'tcx InternalSubsts<'tcx>; impl<'tcx> InternalSubsts<'tcx> { /// Checks whether all elements of this list are types, if so, transmute. pub fn try_as_type_list(&'tcx self) -> Option<&'tcx List<Ty<'tcx>>> { - if self.iter().all(|arg| matches!(arg.unpack(), GenericArgKind::Type(_))) { + self.iter().all(|arg| matches!(arg.unpack(), GenericArgKind::Type(_))).then(|| { assert_eq!(TYPE_TAG, 0); // SAFETY: All elements are types, see `List<Ty<'tcx>>::as_substs`. - Some(unsafe { &*(self as *const List<GenericArg<'tcx>> as *const List<Ty<'tcx>>) }) - } else { - None - } + unsafe { &*(self as *const List<GenericArg<'tcx>> as *const List<Ty<'tcx>>) } + }) } /// Interpret these substitutions as the substitutions of a closure type. @@ -318,7 +319,7 @@ impl<'tcx> InternalSubsts<'tcx> { let count = defs.count(); let mut substs = SmallVec::with_capacity(count); Self::fill_item(&mut substs, tcx, defs, &mut mk_kind); - tcx.intern_substs(&substs) + tcx.mk_substs(&substs) } pub fn extend_to<F>(&self, tcx: TyCtxt<'tcx>, def_id: DefId, mut mk_kind: F) -> SubstsRef<'tcx> @@ -467,26 +468,33 @@ impl<'tcx> InternalSubsts<'tcx> { target_substs: SubstsRef<'tcx>, ) -> SubstsRef<'tcx> { let defs = tcx.generics_of(source_ancestor); - tcx.mk_substs(target_substs.iter().chain(self.iter().skip(defs.params.len()))) + tcx.mk_substs_from_iter(target_substs.iter().chain(self.iter().skip(defs.params.len()))) } pub fn truncate_to(&self, tcx: TyCtxt<'tcx>, generics: &ty::Generics) -> SubstsRef<'tcx> { - tcx.mk_substs(self.iter().take(generics.count())) + tcx.mk_substs_from_iter(self.iter().take(generics.count())) } } -impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for SubstsRef<'tcx> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { // This code is hot enough that it's worth specializing for the most // common length lists, to avoid the overhead of `SmallVec` creation. // The match arms are in order of frequency. The 1, 2, and 0 cases are // typically hit in 90--99.99% of cases. When folding doesn't change // the substs, it's faster to reuse the existing substs rather than - // calling `intern_substs`. + // calling `mk_substs`. match self.len() { 1 => { let param0 = self[0].try_fold_with(folder)?; - if param0 == self[0] { Ok(self) } else { Ok(folder.tcx().intern_substs(&[param0])) } + if param0 == self[0] { + Ok(self) + } else { + Ok(folder.interner().mk_substs(&[param0])) + } } 2 => { let param0 = self[0].try_fold_with(folder)?; @@ -494,17 +502,20 @@ impl<'tcx> TypeFoldable<'tcx> for SubstsRef<'tcx> { if param0 == self[0] && param1 == self[1] { Ok(self) } else { - Ok(folder.tcx().intern_substs(&[param0, param1])) + Ok(folder.interner().mk_substs(&[param0, param1])) } } 0 => Ok(self), - _ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_substs(v)), + _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_substs(v)), } } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { - fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> { +impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for &'tcx ty::List<Ty<'tcx>> { + fn try_fold_with<F: FallibleTypeFolder<TyCtxt<'tcx>>>( + self, + folder: &mut F, + ) -> Result<Self, F::Error> { // This code is fairly hot, though not as hot as `SubstsRef`. // // When compiling stage 2, I get the following results: @@ -527,17 +538,17 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> { if param0 == self[0] && param1 == self[1] { Ok(self) } else { - Ok(folder.tcx().intern_type_list(&[param0, param1])) + Ok(folder.interner().mk_type_list(&[param0, param1])) } } - _ => ty::util::fold_list(self, folder, |tcx, v| tcx.intern_type_list(v)), + _ => ty::util::fold_list(self, folder, |tcx, v| tcx.mk_type_list(v)), } } } -impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List<T> { +impl<'tcx, T: TypeVisitable<TyCtxt<'tcx>>> TypeVisitable<TyCtxt<'tcx>> for &'tcx ty::List<T> { #[inline] - fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { + fn visit_with<V: TypeVisitor<TyCtxt<'tcx>>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> { self.iter().try_for_each(|t| t.visit_with(visitor)) } } @@ -553,8 +564,8 @@ impl<'tcx, T: TypeVisitable<'tcx>> TypeVisitable<'tcx> for &'tcx ty::List<T> { pub struct EarlyBinder<T>(pub T); /// For early binders, you should first call `subst` before using any visitors. -impl<'tcx, T> !TypeFoldable<'tcx> for ty::EarlyBinder<T> {} -impl<'tcx, T> !TypeVisitable<'tcx> for ty::EarlyBinder<T> {} +impl<'tcx, T> !TypeFoldable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {} +impl<'tcx, T> !TypeVisitable<TyCtxt<'tcx>> for ty::EarlyBinder<T> {} impl<T> EarlyBinder<T> { pub fn as_ref(&self) -> EarlyBinder<&T> { @@ -615,7 +626,7 @@ impl<T, U> EarlyBinder<(T, U)> { impl<'tcx, 's, I: IntoIterator> EarlyBinder<I> where - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable<TyCtxt<'tcx>>, { pub fn subst_iter( self, @@ -634,7 +645,7 @@ pub struct SubstIter<'s, 'tcx, I: IntoIterator> { impl<'tcx, I: IntoIterator> Iterator for SubstIter<'_, 'tcx, I> where - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable<TyCtxt<'tcx>>, { type Item = I::Item; @@ -650,7 +661,7 @@ where impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIter<'_, 'tcx, I> where I::IntoIter: DoubleEndedIterator, - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable<TyCtxt<'tcx>>, { fn next_back(&mut self) -> Option<Self::Item> { Some(EarlyBinder(self.it.next_back()?).subst(self.tcx, self.substs)) @@ -660,14 +671,14 @@ where impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIter<'_, 'tcx, I> where I::IntoIter: ExactSizeIterator, - I::Item: TypeFoldable<'tcx>, + I::Item: TypeFoldable<TyCtxt<'tcx>>, { } impl<'tcx, 's, I: IntoIterator> EarlyBinder<I> where I::Item: Deref, - <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>, + <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>, { pub fn subst_iter_copied( self, @@ -687,7 +698,7 @@ pub struct SubstIterCopied<'a, 'tcx, I: IntoIterator> { impl<'tcx, I: IntoIterator> Iterator for SubstIterCopied<'_, 'tcx, I> where I::Item: Deref, - <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>, + <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>, { type Item = <I::Item as Deref>::Target; @@ -704,7 +715,7 @@ impl<'tcx, I: IntoIterator> DoubleEndedIterator for SubstIterCopied<'_, 'tcx, I> where I::IntoIter: DoubleEndedIterator, I::Item: Deref, - <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>, + <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>, { fn next_back(&mut self) -> Option<Self::Item> { Some(EarlyBinder(*self.it.next_back()?).subst(self.tcx, self.substs)) @@ -715,7 +726,7 @@ impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIterCopied<'_, 'tcx, I> where I::IntoIter: ExactSizeIterator, I::Item: Deref, - <I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>, + <I::Item as Deref>::Target: Copy + TypeFoldable<TyCtxt<'tcx>>, { } @@ -741,7 +752,7 @@ impl<T: Iterator> Iterator for EarlyBinderIter<T> { } } -impl<'tcx, T: TypeFoldable<'tcx>> ty::EarlyBinder<T> { +impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> { pub fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T { let mut folder = SubstFolder { tcx, substs, binders_passed: 0 }; self.0.fold_with(&mut folder) @@ -758,6 +769,11 @@ impl<'tcx, T: TypeFoldable<'tcx>> ty::EarlyBinder<T> { pub fn subst_identity(self) -> T { self.0 } + + /// Returns the inner value, but only if it contains no bound vars. + pub fn no_bound_vars(self) -> Option<T> { + if !self.0.needs_subst() { Some(self.0) } else { None } + } } /////////////////////////////////////////////////////////////////////////// @@ -771,13 +787,13 @@ struct SubstFolder<'a, 'tcx> { binders_passed: u32, } -impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> { +impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for SubstFolder<'a, 'tcx> { #[inline] - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } - fn fold_binder<T: TypeFoldable<'tcx>>( + fn fold_binder<T: TypeFoldable<TyCtxt<'tcx>>>( &mut self, t: ty::Binder<'tcx, T>, ) -> ty::Binder<'tcx, T> { @@ -970,7 +986,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the /// first case we do not increase the De Bruijn index and in the second case we do. The reason /// is that only in the second case have we passed through a fn binder. - fn shift_vars_through_binders<T: TypeFoldable<'tcx>>(&self, val: T) -> T { + fn shift_vars_through_binders<T: TypeFoldable<TyCtxt<'tcx>>>(&self, val: T) -> T { debug!( "shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})", val, @@ -982,7 +998,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { return val; } - let result = ty::fold::shift_vars(TypeFolder::tcx(self), val, self.binders_passed); + let result = ty::fold::shift_vars(TypeFolder::interner(self), val, self.binders_passed); debug!("shift_vars: shifted result = {:?}", result); result |