summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer/src/infer/canonical/query_response.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer/src/infer/canonical/query_response.rs')
-rw-r--r--compiler/rustc_infer/src/infer/canonical/query_response.rs127
1 files changed, 61 insertions, 66 deletions
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
}