diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:19:50 +0000 |
commit | 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 (patch) | |
tree | d325add32978dbdc1db975a438b3a77d571b1ab8 /compiler/rustc_middle/src/infer | |
parent | Releasing progress-linux version 1.68.2+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.tar.xz rustc-2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35.zip |
Merging upstream version 1.69.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'compiler/rustc_middle/src/infer')
-rw-r--r-- | compiler/rustc_middle/src/infer/canonical.rs | 162 | ||||
-rw-r--r-- | compiler/rustc_middle/src/infer/mod.rs | 3 |
2 files changed, 111 insertions, 54 deletions
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs index 43583b572..7f8fc1774 100644 --- a/compiler/rustc_middle/src/infer/canonical.rs +++ b/compiler/rustc_middle/src/infer/canonical.rs @@ -25,10 +25,8 @@ use crate::infer::MemberConstraint; use crate::mir::ConstraintCategory; use crate::ty::subst::GenericArg; use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt}; -use rustc_index::vec::IndexVec; use rustc_macros::HashStable; use smallvec::SmallVec; -use std::iter; use std::ops::Index; /// A "canonicalized" type `V` is one where all free inference @@ -44,12 +42,12 @@ pub struct Canonical<'tcx, V> { pub type CanonicalVarInfos<'tcx> = &'tcx List<CanonicalVarInfo<'tcx>>; -impl<'tcx> ty::TypeFoldable<'tcx> for CanonicalVarInfos<'tcx> { - fn try_fold_with<F: ty::FallibleTypeFolder<'tcx>>( +impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> { + fn try_fold_with<F: ty::FallibleTypeFolder<TyCtxt<'tcx>>>( self, folder: &mut F, ) -> Result<Self, F::Error> { - ty::util::fold_list(self, folder, |tcx, v| tcx.intern_canonical_var_infos(v)) + ty::util::fold_list(self, folder, |tcx, v| tcx.mk_canonical_var_infos(v)) } } @@ -62,23 +60,23 @@ impl<'tcx> ty::TypeFoldable<'tcx> for CanonicalVarInfos<'tcx> { /// vectors with the original values that were replaced by canonical /// variables. You will need to supply it later to instantiate the /// canonicalized query response. -#[derive(Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyDecodable, TyEncodable)] #[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct CanonicalVarValues<'tcx> { - pub var_values: IndexVec<BoundVar, GenericArg<'tcx>>, + pub var_values: ty::SubstsRef<'tcx>, } impl CanonicalVarValues<'_> { pub fn is_identity(&self) -> bool { - self.var_values.iter_enumerated().all(|(bv, arg)| match arg.unpack() { + self.var_values.iter().enumerate().all(|(bv, arg)| match arg.unpack() { ty::GenericArgKind::Lifetime(r) => { - matches!(*r, ty::ReLateBound(ty::INNERMOST, br) if br.var == bv) + matches!(*r, ty::ReLateBound(ty::INNERMOST, br) if br.var.as_usize() == bv) } ty::GenericArgKind::Type(ty) => { - matches!(*ty.kind(), ty::Bound(ty::INNERMOST, bt) if bt.var == bv) + matches!(*ty.kind(), ty::Bound(ty::INNERMOST, bt) if bt.var.as_usize() == bv) } ty::GenericArgKind::Const(ct) => { - matches!(ct.kind(), ty::ConstKind::Bound(ty::INNERMOST, bc) if bc == bv) + matches!(ct.kind(), ty::ConstKind::Bound(ty::INNERMOST, bc) if bc.as_usize() == bv) } }) } @@ -125,6 +123,11 @@ impl<'tcx> CanonicalVarInfo<'tcx> { self.kind.universe() } + #[must_use] + pub fn with_updated_universe(self, ui: ty::UniverseIndex) -> CanonicalVarInfo<'tcx> { + CanonicalVarInfo { kind: self.kind.with_updated_universe(ui) } + } + pub fn is_existential(&self) -> bool { match self.kind { CanonicalVarKind::Ty(_) => true, @@ -135,6 +138,28 @@ impl<'tcx> CanonicalVarInfo<'tcx> { CanonicalVarKind::PlaceholderConst(_, _) => false, } } + + pub fn is_region(&self) -> bool { + match self.kind { + CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => true, + CanonicalVarKind::Ty(_) + | CanonicalVarKind::PlaceholderTy(_) + | CanonicalVarKind::Const(_, _) + | CanonicalVarKind::PlaceholderConst(_, _) => false, + } + } + + pub fn expect_anon_placeholder(self) -> u32 { + match self.kind { + CanonicalVarKind::Ty(_) + | CanonicalVarKind::Region(_) + | CanonicalVarKind::Const(_, _) => bug!("expected placeholder: {self:?}"), + + CanonicalVarKind::PlaceholderRegion(placeholder) => placeholder.name.expect_anon(), + CanonicalVarKind::PlaceholderTy(placeholder) => placeholder.name.expect_anon(), + CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.name.as_u32(), + } + } } /// Describes the "kind" of the canonical variable. This is a "kind" @@ -179,6 +204,38 @@ impl<'tcx> CanonicalVarKind<'tcx> { CanonicalVarKind::PlaceholderConst(placeholder, _) => placeholder.universe, } } + + /// Replaces the universe of this canonical variable with `ui`. + /// + /// In case this is a float or int variable, this causes an ICE if + /// the updated universe is not the root. + pub fn with_updated_universe(self, ui: ty::UniverseIndex) -> CanonicalVarKind<'tcx> { + match self { + CanonicalVarKind::Ty(kind) => match kind { + CanonicalTyVarKind::General(_) => { + CanonicalVarKind::Ty(CanonicalTyVarKind::General(ui)) + } + CanonicalTyVarKind::Int | CanonicalTyVarKind::Float => { + assert_eq!(ui, ty::UniverseIndex::ROOT); + CanonicalVarKind::Ty(kind) + } + }, + CanonicalVarKind::PlaceholderTy(placeholder) => { + CanonicalVarKind::PlaceholderTy(ty::Placeholder { universe: ui, ..placeholder }) + } + CanonicalVarKind::Region(_) => CanonicalVarKind::Region(ui), + CanonicalVarKind::PlaceholderRegion(placeholder) => { + CanonicalVarKind::PlaceholderRegion(ty::Placeholder { universe: ui, ..placeholder }) + } + CanonicalVarKind::Const(_, ty) => CanonicalVarKind::Const(ui, ty), + CanonicalVarKind::PlaceholderConst(placeholder, ty) => { + CanonicalVarKind::PlaceholderConst( + ty::Placeholder { universe: ui, ..placeholder }, + ty, + ) + } + } + } } /// Rust actually has more than one category of type variables; @@ -215,7 +272,8 @@ pub struct QueryResponse<'tcx, R> { pub value: R, } -#[derive(Clone, Debug, Default, HashStable, TypeFoldable, TypeVisitable, Lift)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct QueryRegionConstraints<'tcx> { pub outlives: Vec<QueryOutlivesConstraint<'tcx>>, pub member_constraints: Vec<MemberConstraint<'tcx>>, @@ -326,10 +384,8 @@ impl<'tcx, V> Canonical<'tcx, V> { } } -pub type QueryOutlivesConstraint<'tcx> = ( - ty::Binder<'tcx, ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>>, - ConstraintCategory<'tcx>, -); +pub type QueryOutlivesConstraint<'tcx> = + (ty::OutlivesPredicate<GenericArg<'tcx>, Region<'tcx>>, ConstraintCategory<'tcx>); TrivialTypeTraversalAndLiftImpls! { for <'tcx> { @@ -339,57 +395,57 @@ TrivialTypeTraversalAndLiftImpls! { } impl<'tcx> CanonicalVarValues<'tcx> { + // Given a list of canonical variables, construct a set of values which are + // the identity response. + pub fn make_identity( + tcx: TyCtxt<'tcx>, + infos: CanonicalVarInfos<'tcx>, + ) -> CanonicalVarValues<'tcx> { + CanonicalVarValues { + var_values: tcx.mk_substs_from_iter(infos.iter().enumerate().map( + |(i, info)| -> ty::GenericArg<'tcx> { + match info.kind { + CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => { + tcx.mk_bound(ty::INNERMOST, ty::BoundVar::from_usize(i).into()).into() + } + CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => { + let br = ty::BoundRegion { + var: ty::BoundVar::from_usize(i), + kind: ty::BrAnon(i as u32, None), + }; + tcx.mk_re_late_bound(ty::INNERMOST, br).into() + } + CanonicalVarKind::Const(_, ty) + | CanonicalVarKind::PlaceholderConst(_, ty) => tcx + .mk_const( + ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_usize(i)), + ty, + ) + .into(), + } + }, + )), + } + } + /// Creates dummy var values which should not be used in a /// canonical response. pub fn dummy() -> CanonicalVarValues<'tcx> { - CanonicalVarValues { var_values: Default::default() } + CanonicalVarValues { var_values: ty::List::empty() } } #[inline] pub fn len(&self) -> usize { self.var_values.len() } - - /// Makes an identity substitution from this one: each bound var - /// is matched to the same bound var, preserving the original kinds. - /// For example, if we have: - /// `self.var_values == [Type(u32), Lifetime('a), Type(u64)]` - /// we'll return a substitution `subst` with: - /// `subst.var_values == [Type(^0), Lifetime(^1), Type(^2)]`. - pub fn make_identity(&self, tcx: TyCtxt<'tcx>) -> Self { - use crate::ty::subst::GenericArgKind; - - CanonicalVarValues { - var_values: iter::zip(&self.var_values, 0..) - .map(|(kind, i)| match kind.unpack() { - GenericArgKind::Type(..) => { - tcx.mk_ty(ty::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i).into())).into() - } - GenericArgKind::Lifetime(..) => { - let br = ty::BoundRegion { - var: ty::BoundVar::from_u32(i), - kind: ty::BrAnon(i, None), - }; - tcx.mk_region(ty::ReLateBound(ty::INNERMOST, br)).into() - } - GenericArgKind::Const(ct) => tcx - .mk_const( - ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from_u32(i)), - ct.ty(), - ) - .into(), - }) - .collect(), - } - } } impl<'a, 'tcx> IntoIterator for &'a CanonicalVarValues<'tcx> { type Item = GenericArg<'tcx>; - type IntoIter = ::std::iter::Cloned<::std::slice::Iter<'a, GenericArg<'tcx>>>; + type IntoIter = ::std::iter::Copied<::std::slice::Iter<'a, GenericArg<'tcx>>>; fn into_iter(self) -> Self::IntoIter { - self.var_values.iter().cloned() + self.var_values.iter() } } @@ -397,6 +453,6 @@ impl<'tcx> Index<BoundVar> for CanonicalVarValues<'tcx> { type Output = GenericArg<'tcx>; fn index(&self, value: BoundVar) -> &GenericArg<'tcx> { - &self.var_values[value] + &self.var_values[value.as_usize()] } } diff --git a/compiler/rustc_middle/src/infer/mod.rs b/compiler/rustc_middle/src/infer/mod.rs index 38868c210..2db59f37f 100644 --- a/compiler/rustc_middle/src/infer/mod.rs +++ b/compiler/rustc_middle/src/infer/mod.rs @@ -12,7 +12,8 @@ use rustc_span::Span; /// ```text /// R0 member of [O1..On] /// ``` -#[derive(Debug, Clone, HashStable, TypeFoldable, TypeVisitable, Lift)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)] pub struct MemberConstraint<'tcx> { /// The `DefId` and substs of the opaque type causing this constraint. /// Used for error reporting. |