From 2e00214b3efbdfeefaa0fe9e8b8fd519de7adc35 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:50 +0200 Subject: Merging upstream version 1.69.0+dfsg1. Signed-off-by: Daniel Baumann --- compiler/rustc_infer/src/infer/mod.rs | 199 ++++++++++++++++------------------ 1 file changed, 94 insertions(+), 105 deletions(-) (limited to 'compiler/rustc_infer/src/infer/mod.rs') diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index f0e42c1fc..bd1f96635 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -4,6 +4,7 @@ pub use self::LateBoundRegionConversionTime::*; pub use self::RegionVariableOrigin::*; pub use self::SubregionOrigin::*; pub use self::ValuePairs::*; +pub use combine::ObligationEmittingRelation; use self::opaque_types::OpaqueTypeStorage; pub(crate) use self::undo_log::{InferCtxtUndoLogs, Snapshot, UndoLog}; @@ -28,9 +29,9 @@ use rustc_middle::ty::fold::BoundVarReplacerDelegate; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::relate::RelateResult; use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, SubstsRef}; -use rustc_middle::ty::visit::TypeVisitable; +use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt}; pub use rustc_middle::ty::IntVarValue; -use rustc_middle::ty::{self, GenericParamDefKind, InferConst, Ty, TyCtxt}; +use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt}; use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid}; use rustc_span::symbol::Symbol; use rustc_span::Span; @@ -155,7 +156,7 @@ pub struct InferCtxtInner<'tcx> { undo_log: InferCtxtUndoLogs<'tcx>, /// Caches for opaque type inference. - pub opaque_type_storage: OpaqueTypeStorage<'tcx>, + opaque_type_storage: OpaqueTypeStorage<'tcx>, } impl<'tcx> InferCtxtInner<'tcx> { @@ -194,41 +195,17 @@ impl<'tcx> InferCtxtInner<'tcx> { } #[inline] - fn int_unification_table( - &mut self, - ) -> ut::UnificationTable< - ut::InPlace< - ty::IntVid, - &mut ut::UnificationStorage, - &mut InferCtxtUndoLogs<'tcx>, - >, - > { + fn int_unification_table(&mut self) -> UnificationTable<'_, 'tcx, ty::IntVid> { self.int_unification_storage.with_log(&mut self.undo_log) } #[inline] - fn float_unification_table( - &mut self, - ) -> ut::UnificationTable< - ut::InPlace< - ty::FloatVid, - &mut ut::UnificationStorage, - &mut InferCtxtUndoLogs<'tcx>, - >, - > { + fn float_unification_table(&mut self) -> UnificationTable<'_, 'tcx, ty::FloatVid> { self.float_unification_storage.with_log(&mut self.undo_log) } #[inline] - fn const_unification_table( - &mut self, - ) -> ut::UnificationTable< - ut::InPlace< - ty::ConstVid<'tcx>, - &mut ut::UnificationStorage>, - &mut InferCtxtUndoLogs<'tcx>, - >, - > { + fn const_unification_table(&mut self) -> UnificationTable<'_, 'tcx, ty::ConstVid<'tcx>> { self.const_unification_storage.with_log(&mut self.undo_log) } @@ -263,7 +240,7 @@ pub struct InferCtxt<'tcx> { /// short lived InferCtxt within queries. The opaque type obligations are forwarded /// to the outside until the end up in an `InferCtxt` for typeck or borrowck. /// - /// It is default value is `DefiningAnchor::Error`, this way it is easier to catch errors that + /// Its default value is `DefiningAnchor::Error`, this way it is easier to catch errors that /// might come up during inference or typeck. pub defining_use_anchor: DefiningAnchor, @@ -616,7 +593,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> { canonical: &Canonical<'tcx, T>, ) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>) where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { let infcx = self.build(); let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical); @@ -696,7 +673,7 @@ impl<'tcx> InferCtxt<'tcx> { self.in_snapshot.get() } - pub fn freshen>(&self, t: T) -> T { + pub fn freshen>>(&self, t: T) -> T { t.fold_with(&mut self.freshener()) } @@ -879,30 +856,20 @@ impl<'tcx> InferCtxt<'tcx> { self.inner.borrow_mut().unwrap_region_constraints().add_given(sub, sup); } - pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> + pub fn can_sub(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool where T: at::ToTrace<'tcx>, { let origin = &ObligationCause::dummy(); - self.probe(|_| { - self.at(origin, param_env).sub(a, b).map(|InferOk { obligations: _, .. }| { - // Ignore obligations, since we are unrolling - // everything anyway. - }) - }) + self.probe(|_| self.at(origin, param_env).sub(a, b).is_ok()) } - pub fn can_eq(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> UnitResult<'tcx> + pub fn can_eq(&self, param_env: ty::ParamEnv<'tcx>, a: T, b: T) -> bool where T: at::ToTrace<'tcx>, { let origin = &ObligationCause::dummy(); - self.probe(|_| { - self.at(origin, param_env).eq(a, b).map(|InferOk { obligations: _, .. }| { - // Ignore obligations, since we are unrolling - // everything anyway. - }) - }) + self.probe(|_| self.at(origin, param_env).eq(a, b).is_ok()) } #[instrument(skip(self), level = "debug")] @@ -995,7 +962,7 @@ impl<'tcx> InferCtxt<'tcx> { Ok(self.commit_if_ok(|_snapshot| { let ty::SubtypePredicate { a_is_expected, a, b } = - self.replace_bound_vars_with_placeholders(predicate); + self.instantiate_binder_with_placeholders(predicate); let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?; @@ -1008,7 +975,7 @@ impl<'tcx> InferCtxt<'tcx> { cause: &traits::ObligationCause<'tcx>, predicate: ty::PolyRegionOutlivesPredicate<'tcx>, ) { - let ty::OutlivesPredicate(r_a, r_b) = self.replace_bound_vars_with_placeholders(predicate); + let ty::OutlivesPredicate(r_a, r_b) = self.instantiate_binder_with_placeholders(predicate); let origin = SubregionOrigin::from_obligation_cause(cause, || RelateRegionParamBound(cause.span)); self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b` @@ -1102,7 +1069,7 @@ impl<'tcx> InferCtxt<'tcx> { ) -> ty::Region<'tcx> { let region_var = self.inner.borrow_mut().unwrap_region_constraints().new_region_var(universe, origin); - self.tcx.mk_region(ty::ReVar(region_var)) + self.tcx.mk_re_var(region_var) } /// Return the universe that the region `r` was created in. For @@ -1120,11 +1087,13 @@ impl<'tcx> InferCtxt<'tcx> { } /// Just a convenient wrapper of `next_region_var` for using during NLL. + #[instrument(skip(self), level = "debug")] pub fn next_nll_region_var(&self, origin: NllRegionVariableOrigin) -> ty::Region<'tcx> { self.next_region_var(RegionVariableOrigin::Nll(origin)) } /// Just a convenient wrapper of `next_region_var` for using during NLL. + #[instrument(skip(self), level = "debug")] pub fn next_nll_region_var_in_universe( &self, origin: NllRegionVariableOrigin, @@ -1175,7 +1144,15 @@ impl<'tcx> InferCtxt<'tcx> { origin, val: ConstVariableValue::Unknown { universe: self.universe() }, }); - self.tcx.mk_const(const_var_id, self.tcx.type_of(param.def_id)).into() + self.tcx + .mk_const( + const_var_id, + self.tcx + .type_of(param.def_id) + .no_bound_vars() + .expect("const parameter types cannot be generic"), + ) + .into() } } } @@ -1370,7 +1347,7 @@ impl<'tcx> InferCtxt<'tcx> { /// will be resolving them as well, e.g. in a loop). pub fn shallow_resolve(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { value.fold_with(&mut ShallowResolver { infcx: self }) } @@ -1387,10 +1364,10 @@ impl<'tcx> InferCtxt<'tcx> { /// at will. pub fn resolve_vars_if_possible(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { - if !value.needs_infer() { - return value; // Avoid duplicated subst-folding. + if !value.has_non_region_infer() { + return value; } let mut r = resolve::OpportunisticVarResolver::new(self); value.fold_with(&mut r) @@ -1398,7 +1375,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn resolve_numeric_literals_with_default(&self, value: T) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable>, { if !value.needs_infer() { return value; // Avoid duplicated subst-folding. @@ -1413,7 +1390,7 @@ impl<'tcx> InferCtxt<'tcx> { value: &T, ) -> Option<(ty::Term<'tcx>, Option)> where - T: TypeVisitable<'tcx>, + T: TypeVisitable>, { value.visit_with(&mut resolve::UnresolvedTypeOrConstFinder::new(self)).break_value() } @@ -1428,17 +1405,14 @@ impl<'tcx> InferCtxt<'tcx> { } } - pub fn fully_resolve>(&self, value: T) -> FixupResult<'tcx, T> { - /*! - * Attempts to resolve all type/region/const variables in - * `value`. Region inference must have been run already (e.g., - * by calling `resolve_regions_and_report_errors`). If some - * variable was never unified, an `Err` results. - * - * This method is idempotent, but it not typically not invoked - * except during the writeback phase. - */ - + /// Attempts to resolve all type/region/const variables in + /// `value`. Region inference must have been run already (e.g., + /// by calling `resolve_regions_and_report_errors`). If some + /// variable was never unified, an `Err` results. + /// + /// This method is idempotent, but it not typically not invoked + /// except during the writeback phase. + pub fn fully_resolve>>(&self, value: T) -> FixupResult<'tcx, T> { let value = resolve::fully_resolve(self, value); assert!( value.as_ref().map_or(true, |value| !value.needs_infer()), @@ -1447,14 +1421,21 @@ impl<'tcx> InferCtxt<'tcx> { value } - pub fn replace_bound_vars_with_fresh_vars( + // Instantiates the bound variables in a given binder with fresh inference + // variables in the current universe. + // + // Use this method if you'd like to find some substitution of the binder's + // variables (e.g. during a method call). If there isn't a [`LateBoundRegionConversionTime`] + // that corresponds to your use case, consider whether or not you should + // use [`InferCtxt::instantiate_binder_with_placeholders`] instead. + pub fn instantiate_binder_with_fresh_vars( &self, span: Span, lbrct: LateBoundRegionConversionTime, value: ty::Binder<'tcx, T>, ) -> T where - T: TypeFoldable<'tcx> + Copy, + T: TypeFoldable> + Copy, { if let Some(inner) = value.no_bound_vars() { return inner; @@ -1746,7 +1727,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { // in this case. The typechecker should only ever report type errors involving mismatched // types using one of these methods, and should not call span_err directly for such // errors. - pub fn type_error_struct_with_diag( &self, sp: Span, @@ -1844,8 +1824,8 @@ struct InferenceLiteralEraser<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> TypeFolder<'tcx> for InferenceLiteralEraser<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { +impl<'tcx> TypeFolder> for InferenceLiteralEraser<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } @@ -1862,17 +1842,41 @@ struct ShallowResolver<'a, 'tcx> { infcx: &'a InferCtxt<'tcx>, } -impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'a, 'tcx> TypeFolder> for ShallowResolver<'a, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.infcx.tcx } /// If `ty` is a type variable of some kind, resolve it one level /// (but do not resolve types found in the result). If `typ` is /// not a type variable, just return it unmodified. + #[inline] fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - match *ty.kind() { - ty::Infer(ty::TyVar(v)) => { + if let ty::Infer(v) = ty.kind() { self.fold_infer_ty(*v).unwrap_or(ty) } else { ty } + } + + fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { + if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() { + self.infcx + .inner + .borrow_mut() + .const_unification_table() + .probe_value(vid) + .val + .known() + .unwrap_or(ct) + } else { + ct + } + } +} + +impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { + // This is separate from `fold_ty` to keep that method small and inlinable. + #[inline(never)] + fn fold_infer_ty(&mut self, v: InferTy) -> Option> { + match v { + ty::TyVar(v) => { // Not entirely obvious: if `typ` is a type variable, // it can be resolved to an int/float variable, which // can then be recursively resolved, hence the @@ -1886,41 +1890,26 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { // Note: if these two lines are combined into one we get // dynamic borrow errors on `self.inner`. let known = self.infcx.inner.borrow_mut().type_variables().probe(v).known(); - known.map_or(ty, |t| self.fold_ty(t)) + known.map(|t| self.fold_ty(t)) } - ty::Infer(ty::IntVar(v)) => self + ty::IntVar(v) => self .infcx .inner .borrow_mut() .int_unification_table() .probe_value(v) - .map_or(ty, |v| v.to_type(self.infcx.tcx)), + .map(|v| v.to_type(self.infcx.tcx)), - ty::Infer(ty::FloatVar(v)) => self + ty::FloatVar(v) => self .infcx .inner .borrow_mut() .float_unification_table() .probe_value(v) - .map_or(ty, |v| v.to_type(self.infcx.tcx)), - - _ => ty, - } - } + .map(|v| v.to_type(self.infcx.tcx)), - fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> { - if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() { - self.infcx - .inner - .borrow_mut() - .const_unification_table() - .probe_value(vid) - .val - .known() - .unwrap_or(ct) - } else { - ct + ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => None, } } } @@ -2044,24 +2033,24 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( ) -> SubstsRef<'tcx> { struct ReplaceParamAndInferWithPlaceholder<'tcx> { tcx: TyCtxt<'tcx>, - idx: usize, + idx: u32, } - impl<'tcx> TypeFolder<'tcx> for ReplaceParamAndInferWithPlaceholder<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { + impl<'tcx> TypeFolder> for ReplaceParamAndInferWithPlaceholder<'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { if let ty::Infer(_) = t.kind() { - self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + self.tcx.mk_placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, - name: ty::BoundVar::from_usize({ + name: ty::BoundTyKind::Anon({ let idx = self.idx; self.idx += 1; idx }), - })) + }) } else { t.super_fold_with(self) } @@ -2077,7 +2066,7 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>( self.tcx.mk_const( ty::PlaceholderConst { universe: ty::UniverseIndex::ROOT, - name: ty::BoundVar::from_usize({ + name: ty::BoundVar::from_u32({ let idx = self.idx; self.idx += 1; idx -- cgit v1.2.3