Move canonicalization code around
This commit is contained in:
parent
7f89c7c32d
commit
a61616a016
@ -1,7 +1,6 @@
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::at::ToTrace;
|
||||
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
|
||||
use rustc_infer::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarValues};
|
||||
use rustc_infer::infer::canonical::CanonicalVarValues;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::{
|
||||
DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, TyCtxtInferExt,
|
||||
@ -9,9 +8,7 @@ use rustc_infer::infer::{
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
||||
use rustc_middle::traits::solve::{
|
||||
CanonicalGoal, Certainty, ExternalConstraints, ExternalConstraintsData, MaybeCause, QueryResult,
|
||||
};
|
||||
use rustc_middle::traits::solve::{CanonicalGoal, Certainty, MaybeCause, QueryResult};
|
||||
use rustc_middle::ty::{
|
||||
self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
||||
TypeVisitor,
|
||||
@ -21,11 +18,12 @@ use std::ops::ControlFlow;
|
||||
|
||||
use crate::traits::specialization_graph;
|
||||
|
||||
use super::canonical::{CanonicalizeMode, Canonicalizer};
|
||||
use super::search_graph::{self, OverflowHandler};
|
||||
use super::SolverMode;
|
||||
use super::{search_graph::SearchGraph, Goal};
|
||||
|
||||
mod canonical;
|
||||
|
||||
pub struct EvalCtxt<'a, 'tcx> {
|
||||
/// The inference context that backs (mostly) inference and placeholder terms
|
||||
/// instantiated while solving goals.
|
||||
@ -414,7 +412,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
|
||||
match self.infcx.probe_ty_var(vid) {
|
||||
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
|
||||
Err(universe) => universe == self.universe(),
|
||||
Err(universe) => universe == self.infcx.universe(),
|
||||
}
|
||||
} else {
|
||||
false
|
||||
@ -424,7 +422,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
|
||||
match self.infcx.probe_const_var(vid) {
|
||||
Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
|
||||
Err(universe) => universe == self.universe(),
|
||||
Err(universe) => universe == self.infcx.universe(),
|
||||
}
|
||||
} else {
|
||||
false
|
||||
@ -566,22 +564,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
self.infcx.fresh_substs_for_item(DUMMY_SP, def_id)
|
||||
}
|
||||
|
||||
pub(super) fn universe(&self) -> ty::UniverseIndex {
|
||||
self.infcx.universe()
|
||||
}
|
||||
|
||||
pub(super) fn create_next_universe(&self) -> ty::UniverseIndex {
|
||||
self.infcx.create_next_universe()
|
||||
}
|
||||
|
||||
pub(super) fn instantiate_canonical_var(
|
||||
&self,
|
||||
cv_info: CanonicalVarInfo<'tcx>,
|
||||
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
|
||||
) -> ty::GenericArg<'tcx> {
|
||||
self.infcx.instantiate_canonical_var(DUMMY_SP, cv_info, universe_map)
|
||||
}
|
||||
|
||||
pub(super) fn translate_substs(
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
@ -621,35 +603,4 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
crate::traits::wf::unnormalized_obligations(self.infcx, param_env, arg)
|
||||
.map(|obligations| obligations.into_iter().map(|obligation| obligation.into()))
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
pub(super) fn compute_external_query_constraints(
|
||||
&self,
|
||||
) -> Result<ExternalConstraints<'tcx>, NoSolution> {
|
||||
// Cannot use `take_registered_region_obligations` as we may compute the response
|
||||
// inside of a `probe` whenever we have multiple choices inside of the solver.
|
||||
let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned();
|
||||
let region_constraints = self.infcx.with_region_constraints(|region_constraints| {
|
||||
make_query_region_constraints(
|
||||
self.tcx(),
|
||||
region_obligations
|
||||
.iter()
|
||||
.map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())),
|
||||
region_constraints,
|
||||
)
|
||||
});
|
||||
let opaque_types = self.infcx.clone_opaque_types_for_query_response();
|
||||
Ok(self
|
||||
.tcx()
|
||||
.mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types }))
|
||||
}
|
||||
|
||||
pub(super) fn canonicalize<T: TypeFoldable<TyCtxt<'tcx>>>(
|
||||
&self,
|
||||
canonicalize_mode: CanonicalizeMode,
|
||||
variables: &mut Vec<ty::GenericArg<'tcx>>,
|
||||
value: T,
|
||||
) -> Canonical<'tcx, T> {
|
||||
Canonicalizer::canonicalize(self.infcx, canonicalize_mode, variables, value)
|
||||
}
|
||||
}
|
||||
|
@ -8,20 +8,19 @@
|
||||
/// section of the [rustc-dev-guide][c].
|
||||
///
|
||||
/// [c]: https://rustc-dev-guide.rust-lang.org/solve/canonicalization.html
|
||||
pub use self::canonicalize::{CanonicalizeMode, Canonicalizer};
|
||||
|
||||
use super::{CanonicalGoal, Certainty, EvalCtxt, Goal};
|
||||
use super::{CanonicalResponse, QueryResult, Response};
|
||||
use crate::solve::canonicalize::{CanonicalizeMode, Canonicalizer};
|
||||
use crate::solve::{CanonicalResponse, QueryResult, Response};
|
||||
use rustc_infer::infer::canonical::query_response::make_query_region_constraints;
|
||||
use rustc_infer::infer::canonical::CanonicalVarValues;
|
||||
use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_infer::traits::solve::ExternalConstraintsData;
|
||||
use rustc_middle::traits::query::NoSolution;
|
||||
use rustc_middle::traits::solve::{ExternalConstraints, ExternalConstraintsData};
|
||||
use rustc_middle::ty::{self, GenericArgKind};
|
||||
use rustc_span::DUMMY_SP;
|
||||
use std::iter;
|
||||
use std::ops::Deref;
|
||||
|
||||
mod canonicalize;
|
||||
|
||||
impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
/// Canonicalizes the goal remembering the original values
|
||||
/// for each bound variable.
|
||||
@ -30,7 +29,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
goal: Goal<'tcx, ty::Predicate<'tcx>>,
|
||||
) -> (Vec<ty::GenericArg<'tcx>>, CanonicalGoal<'tcx>) {
|
||||
let mut orig_values = Default::default();
|
||||
let canonical_goal = self.canonicalize(CanonicalizeMode::Input, &mut orig_values, goal);
|
||||
let canonical_goal = Canonicalizer::canonicalize(
|
||||
self.infcx,
|
||||
CanonicalizeMode::Input,
|
||||
&mut orig_values,
|
||||
goal,
|
||||
);
|
||||
(orig_values, canonical_goal)
|
||||
}
|
||||
|
||||
@ -41,7 +45,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
/// - `external_constraints`: additional constraints which aren't expressable
|
||||
/// using simple unification of inference variables.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
pub(super) fn evaluate_added_goals_and_make_canonical_response(
|
||||
pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
|
||||
&mut self,
|
||||
certainty: Certainty,
|
||||
) -> QueryResult<'tcx> {
|
||||
@ -51,7 +55,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
let external_constraints = self.compute_external_query_constraints()?;
|
||||
|
||||
let response = Response { var_values: self.var_values, external_constraints, certainty };
|
||||
let canonical = self.canonicalize(
|
||||
let canonical = Canonicalizer::canonicalize(
|
||||
self.infcx,
|
||||
CanonicalizeMode::Response { max_input_universe: self.max_input_universe },
|
||||
&mut Default::default(),
|
||||
response,
|
||||
@ -59,6 +64,26 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
Ok(canonical)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self), ret)]
|
||||
fn compute_external_query_constraints(&self) -> Result<ExternalConstraints<'tcx>, NoSolution> {
|
||||
// Cannot use `take_registered_region_obligations` as we may compute the response
|
||||
// inside of a `probe` whenever we have multiple choices inside of the solver.
|
||||
let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned();
|
||||
let region_constraints = self.infcx.with_region_constraints(|region_constraints| {
|
||||
make_query_region_constraints(
|
||||
self.tcx(),
|
||||
region_obligations
|
||||
.iter()
|
||||
.map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())),
|
||||
region_constraints,
|
||||
)
|
||||
});
|
||||
let opaque_types = self.infcx.clone_opaque_types_for_query_response();
|
||||
Ok(self
|
||||
.tcx()
|
||||
.mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types }))
|
||||
}
|
||||
|
||||
/// After calling a canonical query, we apply the constraints returned
|
||||
/// by the query using this function.
|
||||
///
|
||||
@ -98,10 +123,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
// FIXME: Longterm canonical queries should deal with all placeholders
|
||||
// created inside of the query directly instead of returning them to the
|
||||
// caller.
|
||||
let prev_universe = self.universe();
|
||||
let prev_universe = self.infcx.universe();
|
||||
let universes_created_in_query = response.max_universe.index() + 1;
|
||||
for _ in 0..universes_created_in_query {
|
||||
self.create_next_universe();
|
||||
self.infcx.create_next_universe();
|
||||
}
|
||||
|
||||
let var_values = response.value.var_values;
|
||||
@ -144,7 +169,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
// A variable from inside a binder of the query. While ideally these shouldn't
|
||||
// exist at all (see the FIXME at the start of this method), we have to deal with
|
||||
// them for now.
|
||||
self.instantiate_canonical_var(info, |idx| {
|
||||
self.infcx.instantiate_canonical_var(DUMMY_SP, info, |idx| {
|
||||
ty::UniverseIndex::from(prev_universe.index() + idx.index())
|
||||
})
|
||||
} else if info.is_existential() {
|
||||
@ -158,7 +183,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
if let Some(v) = opt_values[index] {
|
||||
v
|
||||
} else {
|
||||
self.instantiate_canonical_var(info, |_| prev_universe)
|
||||
self.infcx.instantiate_canonical_var(DUMMY_SP, info, |_| prev_universe)
|
||||
}
|
||||
} else {
|
||||
// For placeholders which were already part of the input, we simply map this
|
@ -15,8 +15,7 @@ use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::canonical::{Canonical, CanonicalVarValues};
|
||||
use rustc_infer::traits::query::NoSolution;
|
||||
use rustc_middle::traits::solve::{
|
||||
CanonicalGoal, CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult,
|
||||
Response,
|
||||
CanonicalResponse, Certainty, ExternalConstraintsData, Goal, QueryResult, Response,
|
||||
};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{
|
||||
@ -24,7 +23,7 @@ use rustc_middle::ty::{
|
||||
};
|
||||
|
||||
mod assembly;
|
||||
mod canonical;
|
||||
mod canonicalize;
|
||||
mod eval_ctxt;
|
||||
mod fulfill;
|
||||
mod project_goals;
|
||||
|
Loading…
x
Reference in New Issue
Block a user