summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/canonical
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer/src/infer/canonical')
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs58
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs29
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs127
-rw-r--r--compiler/rustc_infer/src/infer/canonical/substitute.rs21
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),
},