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_infer/src/infer/canonical | |
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_infer/src/infer/canonical')
4 files changed, 120 insertions, 115 deletions
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index 091635e6c..678c4a0be 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -12,7 +12,7 @@ use crate::infer::InferCtxt; use rustc_middle::ty::flags::FlagComputation; use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable}; use rustc_middle::ty::subst::GenericArg; -use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags}; +use rustc_middle::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags, TypeVisitableExt}; use std::sync::atomic::Ordering; use rustc_data_structures::fx::FxHashMap; @@ -41,7 +41,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); @@ -50,7 +50,7 @@ impl<'tcx> InferCtxt<'tcx> { /// Like [Self::canonicalize_query], but preserves distinct universes. For /// example, canonicalizing `&'?0: Trait<'?1>`, where `'?0` is in `U1` and - /// `'?1` is in `U3` would be canonicalized to have ?0` in `U1` and `'?1` + /// `'?1` is in `U3` would be canonicalized to have `?0` in `U1` and `'?1` /// in `U2`. /// /// This is used for Chalk integration. @@ -60,7 +60,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); @@ -100,7 +100,7 @@ impl<'tcx> InferCtxt<'tcx> { /// [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html#canonicalizing-the-query-result pub fn canonicalize_response<V>(&self, value: V) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { let mut query_state = OriginalQueryValues::default(); Canonicalizer::canonicalize( @@ -114,7 +114,7 @@ impl<'tcx> InferCtxt<'tcx> { pub fn canonicalize_user_type_annotation<V>(&self, value: V) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { let mut query_state = OriginalQueryValues::default(); Canonicalizer::canonicalize( @@ -136,7 +136,7 @@ impl<'tcx> InferCtxt<'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { self.tcx.sess.perf_stats.queries_canonicalized.fetch_add(1, Ordering::Relaxed); @@ -203,12 +203,10 @@ impl CanonicalizeMode for CanonicalizeQueryResponse { // rust-lang/rust#57464: `impl Trait` can leak local // scopes (in manner violating typeck). Therefore, use // `delay_span_bug` to allow type error over an ICE. - ty::tls::with(|tcx| { - tcx.sess.delay_span_bug( - rustc_span::DUMMY_SP, - &format!("unexpected region in query response: `{:?}`", r), - ); - }); + canonicalizer.tcx.sess.delay_span_bug( + rustc_span::DUMMY_SP, + &format!("unexpected region in query response: `{:?}`", r), + ); r } } @@ -328,14 +326,14 @@ struct Canonicalizer<'cx, 'tcx> { binder_index: ty::DebruijnIndex, } -impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { - fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { +impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> { + fn interner(&self) -> TyCtxt<'tcx> { self.tcx } fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T> where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { self.binder_index.shift_in(1); let t = t.super_fold_with(self); @@ -365,12 +363,13 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { opportunistically resolved to {:?}", vid, resolved_vid ); - let r = self.tcx.reuse_or_mk_region(r, ty::ReVar(resolved_vid)); + let r = self.tcx.mk_re_var(resolved_vid); self.canonicalize_mode.canonicalize_free_region(self, r) } ty::ReStatic | ty::ReEarlyBound(..) + | ty::ReError(_) | ty::ReFree(_) | ty::RePlaceholder(..) | ty::ReErased => self.canonicalize_mode.canonicalize_free_region(self, r), @@ -419,10 +418,15 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { bug!("encountered a fresh type during canonicalization") } - ty::Placeholder(placeholder) => self.canonicalize_ty_var( - CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) }, - t, - ), + ty::Placeholder(mut placeholder) => { + if !self.canonicalize_mode.preserve_universes() { + placeholder.universe = ty::UniverseIndex::ROOT; + } + self.canonicalize_ty_var( + CanonicalVarInfo { kind: CanonicalVarKind::PlaceholderTy(placeholder) }, + t, + ) + } ty::Bound(debruijn, _) => { if debruijn >= self.binder_index { @@ -435,6 +439,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) + | ty::GeneratorWitnessMIR(..) | ty::Bool | ty::Char | ty::Int(..) @@ -525,7 +530,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { query_state: &mut OriginalQueryValues<'tcx>, ) -> Canonical<'tcx, V> where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { let needs_canonical_flags = if canonicalize_region_mode.any() { TypeFlags::NEEDS_INFER | @@ -567,7 +572,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { debug_assert!(!out_value.needs_infer() && !out_value.has_placeholders()); let canonical_variables = - tcx.intern_canonical_var_infos(&canonicalizer.universe_canonicalized_variables()); + tcx.mk_canonical_var_infos(&canonicalizer.universe_canonicalized_variables()); let max_universe = canonical_variables .iter() @@ -737,8 +742,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { ) -> ty::Region<'tcx> { let var = self.canonical_var(info, r.into()); let br = ty::BoundRegion { var, kind: ty::BrAnon(var.as_u32(), None) }; - let region = ty::ReLateBound(self.binder_index, br); - self.tcx().mk_region(region) + self.interner().mk_re_late_bound(self.binder_index, br) } /// Given a type variable `ty_var` of the given kind, first check @@ -752,7 +756,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { self.fold_ty(bound_to) } else { let var = self.canonical_var(info, ty_var.into()); - self.tcx().mk_ty(ty::Bound(self.binder_index, var.into())) + self.interner().mk_bound(self.binder_index, var.into()) } } @@ -771,7 +775,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { self.fold_const(bound_to) } else { let var = self.canonical_var(info, const_var.into()); - self.tcx().mk_const( + self.interner().mk_const( ty::ConstKind::Bound(self.binder_index, var), self.fold_ty(const_var.ty()), ) diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs index e59715b70..ce230afda 100644 --- a/compiler/rustc_infer/src/infer/canonical/mod.rs +++ b/compiler/rustc_infer/src/infer/canonical/mod.rs @@ -26,11 +26,11 @@ use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVari use rustc_index::vec::IndexVec; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::subst::GenericArg; -use rustc_middle::ty::{self, BoundVar, List}; +use rustc_middle::ty::{self, List, TyCtxt}; use rustc_span::source_map::Span; pub use rustc_middle::infer::canonical::*; -use substitute::CanonicalExt; +pub use substitute::CanonicalExt; mod canonicalizer; pub mod query_response; @@ -55,7 +55,7 @@ impl<'tcx> InferCtxt<'tcx> { canonical: &Canonical<'tcx, T>, ) -> (T, CanonicalVarValues<'tcx>) where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { // For each universe that is referred to in the incoming // query, create a universe in our local inference context. In @@ -87,19 +87,24 @@ impl<'tcx> InferCtxt<'tcx> { variables: &List<CanonicalVarInfo<'tcx>>, universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, ) -> CanonicalVarValues<'tcx> { - let var_values: IndexVec<BoundVar, GenericArg<'tcx>> = variables - .iter() - .map(|info| self.instantiate_canonical_var(span, info, &universe_map)) - .collect(); - - CanonicalVarValues { var_values } + CanonicalVarValues { + var_values: self.tcx.mk_substs_from_iter( + variables + .iter() + .map(|info| self.instantiate_canonical_var(span, info, &universe_map)), + ), + } } /// Given the "info" about a canonical variable, creates a fresh /// variable for it. If this is an existentially quantified /// variable, then you'll get a new inference variable; if it is a /// universally quantified variable, you get a placeholder. - fn instantiate_canonical_var( + /// + /// FIXME(-Ztrait-solver=next): This is public because it's used by the + /// new trait solver which has a different canonicalization routine. + /// We should somehow deduplicate all of this. + pub fn instantiate_canonical_var( &self, span: Span, cv_info: CanonicalVarInfo<'tcx>, @@ -123,7 +128,7 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::PlaceholderTy(ty::PlaceholderType { universe, name }) => { let universe_mapped = universe_map(universe); let placeholder_mapped = ty::PlaceholderType { universe: universe_mapped, name }; - self.tcx.mk_ty(ty::Placeholder(placeholder_mapped)).into() + self.tcx.mk_placeholder(placeholder_mapped).into() } CanonicalVarKind::Region(ui) => self @@ -136,7 +141,7 @@ impl<'tcx> InferCtxt<'tcx> { CanonicalVarKind::PlaceholderRegion(ty::PlaceholderRegion { universe, name }) => { let universe_mapped = universe_map(universe); let placeholder_mapped = ty::PlaceholderRegion { universe: universe_mapped, name }; - self.tcx.mk_region(ty::RePlaceholder(placeholder_mapped)).into() + self.tcx.mk_re_placeholder(placeholder_mapped).into() } CanonicalVarKind::Const(ui, ty) => self diff --git a/compiler/rustc_infer/src/infer/canonical/query_response.rs b/compiler/rustc_infer/src/infer/canonical/query_response.rs index 3d49182f0..436d29c24 100644 --- a/compiler/rustc_infer/src/infer/canonical/query_response.rs +++ b/compiler/rustc_infer/src/infer/canonical/query_response.rs @@ -12,12 +12,12 @@ use crate::infer::canonical::{ Canonical, CanonicalQueryResponse, CanonicalVarValues, Certainty, OriginalQueryValues, QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse, }; -use crate::infer::nll_relate::{NormalizationStrategy, TypeRelating, TypeRelatingDelegate}; +use crate::infer::nll_relate::{TypeRelating, TypeRelatingDelegate}; use crate::infer::region_constraints::{Constraint, RegionConstraintData}; use crate::infer::{InferCtxt, InferOk, InferResult, NllRegionVariableOrigin}; use crate::traits::query::{Fallible, NoSolution}; use crate::traits::{Obligation, ObligationCause, PredicateObligation}; -use crate::traits::{PredicateObligations, TraitEngine}; +use crate::traits::{PredicateObligations, TraitEngine, TraitEngineExt}; use rustc_data_structures::captures::Captures; use rustc_index::vec::Idx; use rustc_index::vec::IndexVec; @@ -27,7 +27,7 @@ use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::relate::TypeRelation; use rustc_middle::ty::subst::{GenericArg, GenericArgKind}; use rustc_middle::ty::{self, BoundVar, ToPredicate, Ty, TyCtxt}; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use std::fmt::Debug; use std::iter; @@ -59,7 +59,7 @@ impl<'tcx> InferCtxt<'tcx> { fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Fallible<CanonicalQueryResponse<'tcx, T>> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable<TyCtxt<'tcx>>, Canonical<'tcx, QueryResponse<'tcx, T>>: ArenaAllocatable<'tcx>, { let query_response = self.make_query_response(inference_vars, answer, fulfill_cx)?; @@ -85,7 +85,7 @@ impl<'tcx> InferCtxt<'tcx> { answer: T, ) -> Canonical<'tcx, QueryResponse<'tcx, T>> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable<TyCtxt<'tcx>>, { self.canonicalize_response(QueryResponse { var_values: inference_vars, @@ -106,7 +106,7 @@ impl<'tcx> InferCtxt<'tcx> { fulfill_cx: &mut dyn TraitEngine<'tcx>, ) -> Result<QueryResponse<'tcx, T>, NoSolution> where - T: Debug + TypeFoldable<'tcx>, + T: Debug + TypeFoldable<TyCtxt<'tcx>>, { let tcx = self.tcx; @@ -151,11 +151,21 @@ impl<'tcx> InferCtxt<'tcx> { }) } - /// FIXME: This method should only be used for canonical queries and therefore be private. - /// - /// As the new solver does canonicalization slightly differently, this is also used there - /// for now. This should hopefully change fairly soon. - pub fn take_opaque_types_for_query_response(&self) -> Vec<(Ty<'tcx>, Ty<'tcx>)> { + /// Used by the new solver as that one takes the opaque types at the end of a probe + /// to deal with multiple candidates without having to recompute them. + pub fn clone_opaque_types_for_query_response(&self) -> Vec<(Ty<'tcx>, Ty<'tcx>)> { + self.inner + .borrow() + .opaque_type_storage + .opaque_types + .iter() + .map(|&(k, ref v)| { + (self.tcx.mk_opaque(k.def_id.to_def_id(), k.substs), v.hidden_type.ty) + }) + .collect() + } + + fn take_opaque_types_for_query_response(&self) -> Vec<(Ty<'tcx>, Ty<'tcx>)> { std::mem::take(&mut self.inner.borrow_mut().opaque_type_storage.opaque_types) .into_iter() .map(|(k, v)| (self.tcx.mk_opaque(k.def_id.to_def_id(), k.substs), v.hidden_type.ty)) @@ -180,7 +190,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, R> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { let InferOk { value: result_subst, mut obligations } = self.query_response_substitution(cause, param_env, original_values, query_response)?; @@ -242,7 +252,7 @@ impl<'tcx> InferCtxt<'tcx> { output_query_region_constraints: &mut QueryRegionConstraints<'tcx>, ) -> InferResult<'tcx, R> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { let InferOk { value: result_subst, mut obligations } = self .query_response_substitution_guess(cause, param_env, original_values, query_response)?; @@ -268,14 +278,12 @@ impl<'tcx> InferCtxt<'tcx> { (GenericArgKind::Lifetime(v_o), GenericArgKind::Lifetime(v_r)) => { // To make `v_o = v_r`, we emit `v_o: v_r` and `v_r: v_o`. if v_o != v_r { - output_query_region_constraints.outlives.push(( - ty::Binder::dummy(ty::OutlivesPredicate(v_o.into(), v_r)), - constraint_category, - )); - output_query_region_constraints.outlives.push(( - ty::Binder::dummy(ty::OutlivesPredicate(v_r.into(), v_o)), - constraint_category, - )); + output_query_region_constraints + .outlives + .push((ty::OutlivesPredicate(v_o.into(), v_r), constraint_category)); + output_query_region_constraints + .outlives + .push((ty::OutlivesPredicate(v_r.into(), v_o), constraint_category)); } } @@ -318,10 +326,8 @@ impl<'tcx> InferCtxt<'tcx> { query_response.value.region_constraints.outlives.iter().filter_map(|&r_c| { let r_c = substitute_value(self.tcx, &result_subst, r_c); - // Screen out `'a: 'a` cases -- we skip the binder here but - // only compare the inner values to one another, so they are still at - // consistent binding levels. - let ty::OutlivesPredicate(k1, r2) = r_c.0.skip_binder(); + // Screen out `'a: 'a` cases. + let ty::OutlivesPredicate(k1, r2) = r_c.0; if k1 != r2.into() { Some(r_c) } else { None } }), ); @@ -360,7 +366,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { debug!( "query_response_substitution(original_values={:#?}, query_response={:#?})", @@ -397,6 +403,7 @@ impl<'tcx> InferCtxt<'tcx> { /// will instantiate fresh inference variables for each canonical /// variable instead. Therefore, the result of this method must be /// properly unified + #[instrument(level = "debug", skip(self, cause, param_env))] fn query_response_substitution_guess<R>( &self, cause: &ObligationCause<'tcx>, @@ -405,13 +412,8 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, CanonicalVarValues<'tcx>> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { - debug!( - "query_response_substitution_guess(original_values={:#?}, query_response={:#?})", - original_values, query_response, - ); - // For each new universe created in the query result that did // not appear in the original query, create a local // superuniverse. @@ -482,11 +484,8 @@ impl<'tcx> InferCtxt<'tcx> { // given variable in the loop above, use that. Otherwise, use // a fresh inference variable. let result_subst = CanonicalVarValues { - var_values: query_response - .variables - .iter() - .enumerate() - .map(|(index, info)| { + var_values: self.tcx.mk_substs_from_iter( + query_response.variables.iter().enumerate().map(|(index, info)| { if info.is_existential() { match opt_values[BoundVar::new(index)] { Some(k) => k, @@ -499,8 +498,8 @@ impl<'tcx> InferCtxt<'tcx> { universe_map[u.as_usize()] }) } - }) - .collect(), + }), + ), }; let mut obligations = vec![]; @@ -509,7 +508,9 @@ impl<'tcx> InferCtxt<'tcx> { for &(a, b) in &query_response.value.opaque_types { let a = substitute_value(self.tcx, &result_subst, a); let b = substitute_value(self.tcx, &result_subst, b); - obligations.extend(self.at(cause, param_env).eq(a, b)?.obligations); + debug!(?a, ?b, "constrain opaque type"); + obligations + .extend(self.at(cause, param_env).define_opaque_types(true).eq(a, b)?.obligations); } Ok(InferOk { value: result_subst, obligations }) @@ -530,7 +531,7 @@ impl<'tcx> InferCtxt<'tcx> { query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>, ) -> InferResult<'tcx, ()> where - R: Debug + TypeFoldable<'tcx>, + R: Debug + TypeFoldable<TyCtxt<'tcx>>, { // A closure that yields the result value for the given // canonical variable; this is taken from @@ -562,11 +563,11 @@ impl<'tcx> InferCtxt<'tcx> { pub fn query_outlives_constraint_to_obligation( &self, - predicate: QueryOutlivesConstraint<'tcx>, + (predicate, _): QueryOutlivesConstraint<'tcx>, cause: ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> Obligation<'tcx, ty::Predicate<'tcx>> { - let ty::OutlivesPredicate(k1, r2) = predicate.0.skip_binder(); + let ty::OutlivesPredicate(k1, r2) = predicate; let atom = match k1.unpack() { GenericArgKind::Lifetime(r1) => { @@ -581,7 +582,7 @@ impl<'tcx> InferCtxt<'tcx> { span_bug!(cause.span, "unexpected const outlives {:?}", predicate); } }; - let predicate = predicate.0.rebind(atom); + let predicate = ty::Binder::dummy(atom); Obligation::new(self.tcx, cause, param_env, predicate) } @@ -646,31 +647,25 @@ pub fn make_query_region_constraints<'tcx>( let outlives: Vec<_> = constraints .iter() .map(|(k, origin)| { - // no bound vars in the code above - let constraint = ty::Binder::dummy(match *k { + let constraint = match *k { // Swap regions because we are going from sub (<=) to outlives // (>=). - Constraint::VarSubVar(v1, v2) => ty::OutlivesPredicate( - tcx.mk_region(ty::ReVar(v2)).into(), - tcx.mk_region(ty::ReVar(v1)), - ), + Constraint::VarSubVar(v1, v2) => { + ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), tcx.mk_re_var(v1)) + } Constraint::VarSubReg(v1, r2) => { - ty::OutlivesPredicate(r2.into(), tcx.mk_region(ty::ReVar(v1))) + ty::OutlivesPredicate(r2.into(), tcx.mk_re_var(v1)) } Constraint::RegSubVar(r1, v2) => { - ty::OutlivesPredicate(tcx.mk_region(ty::ReVar(v2)).into(), r1) + ty::OutlivesPredicate(tcx.mk_re_var(v2).into(), r1) } Constraint::RegSubReg(r1, r2) => ty::OutlivesPredicate(r2.into(), r1), - }); + }; (constraint, origin.to_constraint_category()) }) - .chain( - outlives_obligations - // no bound vars in the code above - .map(|(ty, r, constraint_category)| { - (ty::Binder::dummy(ty::OutlivesPredicate(ty.into(), r)), constraint_category) - }), - ) + .chain(outlives_obligations.map(|(ty, r, constraint_category)| { + (ty::OutlivesPredicate(ty.into(), r), constraint_category) + })) .collect(); QueryRegionConstraints { outlives, member_constraints: member_constraints.clone() } @@ -696,13 +691,17 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { self.infcx.create_next_universe() } - fn next_existential_region_var(&mut self, from_forall: bool) -> ty::Region<'tcx> { + fn next_existential_region_var( + &mut self, + from_forall: bool, + _name: Option<Symbol>, + ) -> ty::Region<'tcx> { let origin = NllRegionVariableOrigin::Existential { from_forall }; self.infcx.next_nll_region_var(origin) } fn next_placeholder_region(&mut self, placeholder: ty::PlaceholderRegion) -> ty::Region<'tcx> { - self.infcx.tcx.mk_region(ty::RePlaceholder(placeholder)) + self.infcx.tcx.mk_re_placeholder(placeholder) } fn generalize_existential(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx> { @@ -729,10 +728,6 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for QueryTypeRelatingDelegate<'_, 'tcx> { }); } - fn normalization() -> NormalizationStrategy { - NormalizationStrategy::Eager - } - fn forbid_inference_vars() -> bool { true } diff --git a/compiler/rustc_infer/src/infer/canonical/substitute.rs b/compiler/rustc_infer/src/infer/canonical/substitute.rs index 389afe22e..cac3b4072 100644 --- a/compiler/rustc_infer/src/infer/canonical/substitute.rs +++ b/compiler/rustc_infer/src/infer/canonical/substitute.rs @@ -11,12 +11,14 @@ use rustc_middle::ty::fold::{FnMutDelegate, TypeFoldable}; use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::{self, TyCtxt}; -pub(super) trait CanonicalExt<'tcx, V> { +/// FIXME(-Ztrait-solver=next): This or public because it is shared with the +/// new trait solver implementation. We should deduplicate canonicalization. +pub trait CanonicalExt<'tcx, V> { /// Instantiate the wrapped value, replacing each canonical value /// with the value given in `var_values`. fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V where - V: TypeFoldable<'tcx>; + V: TypeFoldable<TyCtxt<'tcx>>; /// Allows one to apply a substitute to some subset of /// `self.value`. Invoke `projection_fn` with `self.value` to get @@ -31,13 +33,13 @@ pub(super) trait CanonicalExt<'tcx, V> { projection_fn: impl FnOnce(&V) -> T, ) -> T where - T: TypeFoldable<'tcx>; + T: TypeFoldable<TyCtxt<'tcx>>; } impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> { fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V where - V: TypeFoldable<'tcx>, + V: TypeFoldable<TyCtxt<'tcx>>, { self.substitute_projected(tcx, var_values, |value| value.clone()) } @@ -49,7 +51,7 @@ impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> { projection_fn: impl FnOnce(&V) -> T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { assert_eq!(self.variables.len(), var_values.len()); let value = projection_fn(&self.value); @@ -66,22 +68,21 @@ pub(super) fn substitute_value<'tcx, T>( value: T, ) -> T where - T: TypeFoldable<'tcx>, + T: TypeFoldable<TyCtxt<'tcx>>, { if var_values.var_values.is_empty() { value } else { let delegate = FnMutDelegate { - regions: &mut |br: ty::BoundRegion| match var_values.var_values[br.var].unpack() { + regions: &mut |br: ty::BoundRegion| match var_values[br.var].unpack() { GenericArgKind::Lifetime(l) => l, r => bug!("{:?} is a region but value is {:?}", br, r), }, - types: &mut |bound_ty: ty::BoundTy| match var_values.var_values[bound_ty.var].unpack() { + types: &mut |bound_ty: ty::BoundTy| match var_values[bound_ty.var].unpack() { GenericArgKind::Type(ty) => ty, r => bug!("{:?} is a type but value is {:?}", bound_ty, r), }, - consts: &mut |bound_ct: ty::BoundVar, _| match var_values.var_values[bound_ct].unpack() - { + consts: &mut |bound_ct: ty::BoundVar, _| match var_values[bound_ct].unpack() { GenericArgKind::Const(ct) => ct, c => bug!("{:?} is a const but value is {:?}", bound_ct, c), }, |