Dejargnonize subst
This commit is contained in:
parent
084ce5bdb5
commit
3856df059e
128 changed files with 574 additions and 541 deletions
|
@ -1,4 +1,4 @@
|
|||
//! This module contains code to substitute new values into a
|
||||
//! This module contains code to instantiate new values into a
|
||||
//! `Canonical<'tcx, T>`.
|
||||
//!
|
||||
//! For an overview of what canonicalization is and how it fits into
|
||||
|
@ -16,17 +16,17 @@ use rustc_middle::ty::{self, TyCtxt};
|
|||
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
|
||||
fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
|
||||
where
|
||||
V: TypeFoldable<TyCtxt<'tcx>>;
|
||||
|
||||
/// Allows one to apply a substitute to some subset of
|
||||
/// Allows one to apply a instantiation to some subset of
|
||||
/// `self.value`. Invoke `projection_fn` with `self.value` to get
|
||||
/// a value V that is expressed in terms of the same canonical
|
||||
/// variables bound in `self` (usually this extracts from subset
|
||||
/// of `self`). Apply the substitution `var_values` to this value
|
||||
/// of `self`). Apply the instantiation `var_values` to this value
|
||||
/// V, replacing each of the canonical variables.
|
||||
fn substitute_projected<T>(
|
||||
fn instantiate_projected<T>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
var_values: &CanonicalVarValues<'tcx>,
|
||||
|
@ -37,14 +37,14 @@ pub trait CanonicalExt<'tcx, V> {
|
|||
}
|
||||
|
||||
impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> {
|
||||
fn substitute(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
|
||||
fn instantiate(&self, tcx: TyCtxt<'tcx>, var_values: &CanonicalVarValues<'tcx>) -> V
|
||||
where
|
||||
V: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
self.substitute_projected(tcx, var_values, |value| value.clone())
|
||||
self.instantiate_projected(tcx, var_values, |value| value.clone())
|
||||
}
|
||||
|
||||
fn substitute_projected<T>(
|
||||
fn instantiate_projected<T>(
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
var_values: &CanonicalVarValues<'tcx>,
|
||||
|
@ -55,14 +55,14 @@ impl<'tcx, V> CanonicalExt<'tcx, V> for Canonical<'tcx, V> {
|
|||
{
|
||||
assert_eq!(self.variables.len(), var_values.len());
|
||||
let value = projection_fn(&self.value);
|
||||
substitute_value(tcx, var_values, value)
|
||||
instantiate_value(tcx, var_values, value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Substitute the values from `var_values` into `value`. `var_values`
|
||||
/// Instantiate the values from `var_values` into `value`. `var_values`
|
||||
/// must be values for the set of canonical variables that appear in
|
||||
/// `value`.
|
||||
pub(super) fn substitute_value<'tcx, T>(
|
||||
pub(super) fn instantiate_value<'tcx, T>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
var_values: &CanonicalVarValues<'tcx>,
|
||||
value: T,
|
|
@ -30,24 +30,24 @@ use rustc_middle::ty::GenericArg;
|
|||
use rustc_middle::ty::{self, List, Ty, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
|
||||
pub use instantiate::CanonicalExt;
|
||||
pub use rustc_middle::infer::canonical::*;
|
||||
pub use substitute::CanonicalExt;
|
||||
|
||||
mod canonicalizer;
|
||||
mod instantiate;
|
||||
pub mod query_response;
|
||||
mod substitute;
|
||||
|
||||
impl<'tcx> InferCtxt<'tcx> {
|
||||
/// Creates a substitution S for the canonical value with fresh
|
||||
/// Creates an instantiation S for the canonical value with fresh
|
||||
/// inference variables and applies it to the canonical value.
|
||||
/// Returns both the instantiated result *and* the substitution S.
|
||||
/// Returns both the instantiated result *and* the instantiation S.
|
||||
///
|
||||
/// This can be invoked as part of constructing an
|
||||
/// inference context at the start of a query (see
|
||||
/// `InferCtxtBuilder::build_with_canonical`). It basically
|
||||
/// brings the canonical value "into scope" within your new infcx.
|
||||
///
|
||||
/// At the end of processing, the substitution S (once
|
||||
/// At the end of processing, the instantiation S (once
|
||||
/// canonicalized) then represents the values that you computed
|
||||
/// for each of the canonical inputs to your query.
|
||||
pub fn instantiate_canonical_with_fresh_inference_vars<T>(
|
||||
|
@ -73,14 +73,14 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
let canonical_inference_vars =
|
||||
self.instantiate_canonical_vars(span, canonical.variables, |ui| universes[ui]);
|
||||
let result = canonical.substitute(self.tcx, &canonical_inference_vars);
|
||||
let result = canonical.instantiate(self.tcx, &canonical_inference_vars);
|
||||
(result, canonical_inference_vars)
|
||||
}
|
||||
|
||||
/// Given the "infos" about the canonical variables from some
|
||||
/// canonical, creates fresh variables with the same
|
||||
/// characteristics (see `instantiate_canonical_var` for
|
||||
/// details). You can then use `substitute` to instantiate the
|
||||
/// details). You can then use `instantiate` to instantiate the
|
||||
/// canonical variable with these inference variables.
|
||||
fn instantiate_canonical_vars(
|
||||
&self,
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
//!
|
||||
//! [c]: https://rust-lang.github.io/chalk/book/canonical_queries/canonicalization.html
|
||||
|
||||
use crate::infer::canonical::substitute::{substitute_value, CanonicalExt};
|
||||
use crate::infer::canonical::instantiate::{instantiate_value, CanonicalExt};
|
||||
use crate::infer::canonical::{
|
||||
Canonical, CanonicalQueryResponse, CanonicalVarValues, Certainty, OriginalQueryValues,
|
||||
QueryOutlivesConstraint, QueryRegionConstraints, QueryResponse,
|
||||
|
@ -189,18 +189,18 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
where
|
||||
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let InferOk { value: result_subst, mut obligations } =
|
||||
self.query_response_substitution(cause, param_env, original_values, query_response)?;
|
||||
let InferOk { value: result_args, mut obligations } =
|
||||
self.query_response_instantiation(cause, param_env, original_values, query_response)?;
|
||||
|
||||
obligations.extend(self.query_outlives_constraints_into_obligations(
|
||||
cause,
|
||||
param_env,
|
||||
&query_response.value.region_constraints.outlives,
|
||||
&result_subst,
|
||||
&result_args,
|
||||
));
|
||||
|
||||
let user_result: R =
|
||||
query_response.substitute_projected(self.tcx, &result_subst, |q_r| q_r.value.clone());
|
||||
query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone());
|
||||
|
||||
Ok(InferOk { value: user_result, obligations })
|
||||
}
|
||||
|
@ -225,11 +225,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// basic operations as `instantiate_query_response_and_region_obligations` but
|
||||
/// it returns its result differently:
|
||||
///
|
||||
/// - It creates a substitution `S` that maps from the original
|
||||
/// - It creates an instantiation `S` that maps from the original
|
||||
/// query variables to the values computed in the query
|
||||
/// result. If any errors arise, they are propagated back as an
|
||||
/// `Err` result.
|
||||
/// - In the case of a successful substitution, we will append
|
||||
/// - In the case of a successful instantiation, we will append
|
||||
/// `QueryOutlivesConstraint` values onto the
|
||||
/// `output_query_region_constraints` vector for the solver to
|
||||
/// use (if an error arises, some values may also be pushed, but
|
||||
|
@ -239,7 +239,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// that must be processed. In this case, those subobligations
|
||||
/// are propagated back in the return value.
|
||||
/// - Finally, the query result (of type `R`) is propagated back,
|
||||
/// after applying the substitution `S`.
|
||||
/// after applying the instantiation `S`.
|
||||
pub fn instantiate_nll_query_response_and_region_obligations<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
|
@ -251,8 +251,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
where
|
||||
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let InferOk { value: result_subst, mut obligations } = self
|
||||
.query_response_substitution_guess(cause, param_env, original_values, query_response)?;
|
||||
let InferOk { value: result_args, mut obligations } = self
|
||||
.query_response_instantiation_guess(
|
||||
cause,
|
||||
param_env,
|
||||
original_values,
|
||||
query_response,
|
||||
)?;
|
||||
|
||||
// Compute `QueryOutlivesConstraint` values that unify each of
|
||||
// the original values `v_o` that was canonicalized into a
|
||||
|
@ -262,7 +267,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
for (index, original_value) in original_values.var_values.iter().enumerate() {
|
||||
// ...with the value `v_r` of that variable from the query.
|
||||
let result_value = query_response.substitute_projected(self.tcx, &result_subst, |v| {
|
||||
let result_value = query_response.instantiate_projected(self.tcx, &result_args, |v| {
|
||||
v.var_values[BoundVar::new(index)]
|
||||
});
|
||||
match (original_value.unpack(), result_value.unpack()) {
|
||||
|
@ -321,7 +326,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// ...also include the other query region constraints from the query.
|
||||
output_query_region_constraints.outlives.extend(
|
||||
query_response.value.region_constraints.outlives.iter().filter_map(|&r_c| {
|
||||
let r_c = substitute_value(self.tcx, &result_subst, r_c);
|
||||
let r_c = instantiate_value(self.tcx, &result_args, r_c);
|
||||
|
||||
// Screen out `'a: 'a` cases.
|
||||
let ty::OutlivesPredicate(k1, r2) = r_c.0;
|
||||
|
@ -336,26 +341,26 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
.region_constraints
|
||||
.member_constraints
|
||||
.iter()
|
||||
.map(|p_c| substitute_value(self.tcx, &result_subst, p_c.clone())),
|
||||
.map(|p_c| instantiate_value(self.tcx, &result_args, p_c.clone())),
|
||||
);
|
||||
|
||||
let user_result: R =
|
||||
query_response.substitute_projected(self.tcx, &result_subst, |q_r| q_r.value.clone());
|
||||
query_response.instantiate_projected(self.tcx, &result_args, |q_r| q_r.value.clone());
|
||||
|
||||
Ok(InferOk { value: user_result, obligations })
|
||||
}
|
||||
|
||||
/// Given the original values and the (canonicalized) result from
|
||||
/// computing a query, returns a substitution that can be applied
|
||||
/// computing a query, returns an instantiation that can be applied
|
||||
/// to the query result to convert the result back into the
|
||||
/// original namespace.
|
||||
///
|
||||
/// The substitution also comes accompanied with subobligations
|
||||
/// The instantiation also comes accompanied with subobligations
|
||||
/// that arose from unification; these might occur if (for
|
||||
/// example) we are doing lazy normalization and the value
|
||||
/// assigned to a type variable is unified with an unnormalized
|
||||
/// projection.
|
||||
fn query_response_substitution<R>(
|
||||
fn query_response_instantiation<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
@ -366,11 +371,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
debug!(
|
||||
"query_response_substitution(original_values={:#?}, query_response={:#?})",
|
||||
"query_response_instantiation(original_values={:#?}, query_response={:#?})",
|
||||
original_values, query_response,
|
||||
);
|
||||
|
||||
let mut value = self.query_response_substitution_guess(
|
||||
let mut value = self.query_response_instantiation_guess(
|
||||
cause,
|
||||
param_env,
|
||||
original_values,
|
||||
|
@ -378,7 +383,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
)?;
|
||||
|
||||
value.obligations.extend(
|
||||
self.unify_query_response_substitution_guess(
|
||||
self.unify_query_response_instantiation_guess(
|
||||
cause,
|
||||
param_env,
|
||||
original_values,
|
||||
|
@ -392,7 +397,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
}
|
||||
|
||||
/// Given the original values and the (canonicalized) result from
|
||||
/// computing a query, returns a **guess** at a substitution that
|
||||
/// computing a query, returns a **guess** at an instantiation that
|
||||
/// can be applied to the query result to convert the result back
|
||||
/// into the original namespace. This is called a **guess**
|
||||
/// because it uses a quick heuristic to find the values for each
|
||||
|
@ -401,7 +406,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// 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>(
|
||||
fn query_response_instantiation_guess<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
@ -450,7 +455,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
if let ty::Bound(debruijn, b) = *result_value.kind() {
|
||||
// ...in which case we would set `canonical_vars[0]` to `Some(?U)`.
|
||||
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
opt_values[b.var] = Some(*original_value);
|
||||
}
|
||||
|
@ -460,7 +465,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
if let ty::ReBound(debruijn, br) = *result_value {
|
||||
// ... in which case we would set `canonical_vars[0]` to `Some('static)`.
|
||||
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
opt_values[br.var] = Some(*original_value);
|
||||
}
|
||||
|
@ -469,7 +474,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
if let ty::ConstKind::Bound(debruijn, b) = result_value.kind() {
|
||||
// ...in which case we would set `canonical_vars[0]` to `Some(const X)`.
|
||||
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
opt_values[b] = Some(*original_value);
|
||||
}
|
||||
|
@ -477,10 +482,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
// Create a result substitution: if we found a value for a
|
||||
// Create result arguments: if we found a value for a
|
||||
// given variable in the loop above, use that. Otherwise, use
|
||||
// a fresh inference variable.
|
||||
let result_subst = CanonicalVarValues {
|
||||
let result_args = CanonicalVarValues {
|
||||
var_values: self.tcx.mk_args_from_iter(
|
||||
query_response.variables.iter().enumerate().map(|(index, info)| {
|
||||
if info.universe() != ty::UniverseIndex::ROOT {
|
||||
|
@ -511,8 +516,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
// Carry all newly resolved opaque types to the caller's scope
|
||||
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);
|
||||
let a = instantiate_value(self.tcx, &result_args, a);
|
||||
let b = instantiate_value(self.tcx, &result_args, b);
|
||||
debug!(?a, ?b, "constrain opaque type");
|
||||
// We use equate here instead of, for example, just registering the
|
||||
// opaque type's hidden value directly, because we may be instantiating
|
||||
|
@ -532,7 +537,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
);
|
||||
}
|
||||
|
||||
Ok(InferOk { value: result_subst, obligations })
|
||||
Ok(InferOk { value: result_args, obligations })
|
||||
}
|
||||
|
||||
/// Given a "guess" at the values for the canonical variables in
|
||||
|
@ -540,13 +545,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// query result. Often, but not always, this is a no-op, because
|
||||
/// we already found the mapping in the "guessing" step.
|
||||
///
|
||||
/// See also: `query_response_substitution_guess`
|
||||
fn unify_query_response_substitution_guess<R>(
|
||||
/// See also: [`Self::query_response_instantiation_guess`]
|
||||
fn unify_query_response_instantiation_guess<R>(
|
||||
&self,
|
||||
cause: &ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
original_values: &OriginalQueryValues<'tcx>,
|
||||
result_subst: &CanonicalVarValues<'tcx>,
|
||||
result_args: &CanonicalVarValues<'tcx>,
|
||||
query_response: &Canonical<'tcx, QueryResponse<'tcx, R>>,
|
||||
) -> InferResult<'tcx, ()>
|
||||
where
|
||||
|
@ -554,15 +559,15 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
{
|
||||
// A closure that yields the result value for the given
|
||||
// canonical variable; this is taken from
|
||||
// `query_response.var_values` after applying the substitution
|
||||
// `result_subst`.
|
||||
let substituted_query_response = |index: BoundVar| -> GenericArg<'tcx> {
|
||||
query_response.substitute_projected(self.tcx, result_subst, |v| v.var_values[index])
|
||||
// `query_response.var_values` after applying the instantiation
|
||||
// by `result_args`.
|
||||
let instantiated_query_response = |index: BoundVar| -> GenericArg<'tcx> {
|
||||
query_response.instantiate_projected(self.tcx, result_args, |v| v.var_values[index])
|
||||
};
|
||||
|
||||
// Unify the original value for each variable with the value
|
||||
// taken from `query_response` (after applying `result_subst`).
|
||||
self.unify_canonical_vars(cause, param_env, original_values, substituted_query_response)
|
||||
// taken from `query_response` (after applying `result_args`).
|
||||
self.unify_canonical_vars(cause, param_env, original_values, instantiated_query_response)
|
||||
}
|
||||
|
||||
/// Converts the region constraints resulting from a query into an
|
||||
|
@ -571,11 +576,11 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
&'a self,
|
||||
cause: &'a ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
unsubstituted_region_constraints: &'a [QueryOutlivesConstraint<'tcx>],
|
||||
result_subst: &'a CanonicalVarValues<'tcx>,
|
||||
uninstantiated_region_constraints: &'a [QueryOutlivesConstraint<'tcx>],
|
||||
result_args: &'a CanonicalVarValues<'tcx>,
|
||||
) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a + Captures<'tcx> {
|
||||
unsubstituted_region_constraints.iter().map(move |&constraint| {
|
||||
let predicate = substitute_value(self.tcx, result_subst, constraint);
|
||||
uninstantiated_region_constraints.iter().map(move |&constraint| {
|
||||
let predicate = instantiate_value(self.tcx, result_args, constraint);
|
||||
self.query_outlives_constraint_to_obligation(predicate, cause.clone(), param_env)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -679,7 +679,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||
/// inference context that contains each of the bound values
|
||||
/// within instantiated as a fresh variable. The `f` closure is
|
||||
/// invoked with the new infcx, along with the instantiated value
|
||||
/// `V` and a substitution `S`. This substitution `S` maps from
|
||||
/// `V` and a instantiation `S`. This instantiation `S` maps from
|
||||
/// the bound values in `C` to their instantiated values in `V`
|
||||
/// (in other words, `S(C) = V`).
|
||||
pub fn build_with_canonical<T>(
|
||||
|
@ -691,8 +691,8 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
|||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let infcx = self.build();
|
||||
let (value, subst) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
|
||||
(infcx, value, subst)
|
||||
let (value, args) = infcx.instantiate_canonical_with_fresh_inference_vars(span, canonical);
|
||||
(infcx, value, args)
|
||||
}
|
||||
|
||||
pub fn build(&mut self) -> InferCtxt<'tcx> {
|
||||
|
@ -1194,13 +1194,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
}
|
||||
GenericParamDefKind::Type { .. } => {
|
||||
// Create a type inference variable for the given
|
||||
// type parameter definition. The substitutions are
|
||||
// type parameter definition. The generic parameters are
|
||||
// for actual parameters that may be referred to by
|
||||
// the default of this type parameter, if it exists.
|
||||
// e.g., `struct Foo<A, B, C = (A, B)>(...);` when
|
||||
// used in a path such as `Foo::<T, U>::new()` will
|
||||
// use an inference variable for `C` with `[T, U]`
|
||||
// as the substitutions for the default, `(T, U)`.
|
||||
// as the generic parameters for the default, `(T, U)`.
|
||||
let ty_var_id = self.inner.borrow_mut().type_variables().new_var(
|
||||
self.universe(),
|
||||
TypeVariableOrigin {
|
||||
|
@ -1256,7 +1256,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid), ty).into()
|
||||
}
|
||||
|
||||
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
|
||||
/// Given a set of generics defined on a type or impl, returns the generic parameters mapping each
|
||||
/// type/region parameter to a fresh inference variable.
|
||||
pub fn fresh_args_for_item(&self, span: Span, def_id: DefId) -> GenericArgsRef<'tcx> {
|
||||
GenericArgs::for_item(self.tcx, def_id, |param, _| self.var_for_def(span, param))
|
||||
|
@ -1411,7 +1411,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
if !value.has_infer() {
|
||||
return value; // Avoid duplicated subst-folding.
|
||||
return value; // Avoid duplicated type-folding.
|
||||
}
|
||||
let mut r = InferenceLiteralEraser { tcx: self.tcx };
|
||||
value.fold_with(&mut r)
|
||||
|
@ -1458,7 +1458,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// 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
|
||||
// Use this method if you'd like to find some generic parameters of the binder's
|
||||
// variables (e.g. during a method call). If there isn't a [`BoundRegionConversionTime`]
|
||||
// that corresponds to your use case, consider whether or not you should
|
||||
// use [`InferCtxt::enter_forall`] instead.
|
||||
|
@ -1603,10 +1603,10 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// Resolves and evaluates a constant.
|
||||
///
|
||||
/// The constant can be located on a trait like `<A as B>::C`, in which case the given
|
||||
/// substitutions and environment are used to resolve the constant. Alternatively if the
|
||||
/// constant has generic parameters in scope the substitutions are used to evaluate the value of
|
||||
/// generic parameters and environment are used to resolve the constant. Alternatively if the
|
||||
/// constant has generic parameters in scope the instantiations are used to evaluate the value of
|
||||
/// the constant. For example in `fn foo<T>() { let _ = [0; bar::<T>()]; }` the repeat count
|
||||
/// constant `bar::<T>()` requires a substitution for `T`, if the substitution for `T` is still
|
||||
/// constant `bar::<T>()` requires a instantiation for `T`, if the instantiation for `T` is still
|
||||
/// too generic for the constant to be evaluated then `Err(ErrorHandled::TooGeneric)` is
|
||||
/// returned.
|
||||
///
|
||||
|
@ -1652,7 +1652,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
let unevaluated = ty::UnevaluatedConst { def: unevaluated.def, args: args_erased };
|
||||
|
||||
// The return value is the evaluated value which doesn't contain any reference to inference
|
||||
// variables, thus we don't need to substitute back the original values.
|
||||
// variables, thus we don't need to instantiate back the original values.
|
||||
tcx.const_eval_resolve_for_typeck(param_env_erased, unevaluated, span)
|
||||
}
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
/// ```
|
||||
///
|
||||
/// As indicating in the comments above, each of those references
|
||||
/// is (in the compiler) basically a substitution (`args`)
|
||||
/// is (in the compiler) basically generic paramters (`args`)
|
||||
/// applied to the type of a suitable `def_id` (which identifies
|
||||
/// `Foo1` or `Foo2`).
|
||||
///
|
||||
|
|
|
@ -25,7 +25,7 @@ use crate::infer::region_constraints::VerifyIfEq;
|
|||
/// * `None` if `some_type` cannot be made equal to `test_ty`,
|
||||
/// no matter the values of the variables in `exists`.
|
||||
/// * `Some(r)` with a suitable bound (typically the value of `bound_region`, modulo
|
||||
/// any bound existential variables, which will be substituted) for the
|
||||
/// any bound existential variables, which will be instantiated) for the
|
||||
/// type under test.
|
||||
///
|
||||
/// NB: This function uses a simplistic, syntactic version of type equality.
|
||||
|
@ -59,7 +59,7 @@ pub fn extract_verify_if_eq<'tcx>(
|
|||
}
|
||||
} else {
|
||||
// The region does not contain any bound variables, so we don't need
|
||||
// to do any substitution.
|
||||
// to do any instantiation.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
|
|
|
@ -277,7 +277,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
|||
/// ```
|
||||
///
|
||||
/// If we were given the `DefId` of `Foo::Bar`, we would return
|
||||
/// `'a`. You could then apply the substitutions from the
|
||||
/// `'a`. You could then apply the instantiations from the
|
||||
/// projection to convert this into your namespace. This also
|
||||
/// works if the user writes `where <Self as Foo<'a>>::Bar: 'a` on
|
||||
/// the trait. In fact, it works by searching for just such a
|
||||
|
|
|
@ -183,14 +183,14 @@ where
|
|||
fn relate_item_args(
|
||||
&mut self,
|
||||
item_def_id: DefId,
|
||||
a_subst: ty::GenericArgsRef<'tcx>,
|
||||
b_subst: ty::GenericArgsRef<'tcx>,
|
||||
a_arg: ty::GenericArgsRef<'tcx>,
|
||||
b_arg: ty::GenericArgsRef<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::GenericArgsRef<'tcx>> {
|
||||
if self.ambient_variance == ty::Variance::Invariant {
|
||||
// Avoid fetching the variance if we are in an invariant
|
||||
// context; no need, and it can induce dependency cycles
|
||||
// (e.g., #41849).
|
||||
relate::relate_args_invariantly(self, a_subst, b_subst)
|
||||
relate::relate_args_invariantly(self, a_arg, b_arg)
|
||||
} else {
|
||||
let tcx = self.tcx();
|
||||
let opt_variances = tcx.variances_of(item_def_id);
|
||||
|
@ -198,8 +198,8 @@ where
|
|||
self,
|
||||
item_def_id,
|
||||
opt_variances,
|
||||
a_subst,
|
||||
b_subst,
|
||||
a_arg,
|
||||
b_arg,
|
||||
false,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ pub enum TypeVariableOriginKind {
|
|||
AdjustmentType,
|
||||
|
||||
/// In type check, when we are type checking a function that
|
||||
/// returns `-> dyn Foo`, we substitute a type variable for the
|
||||
/// returns `-> dyn Foo`, we instantiate a type variable with the
|
||||
/// return type for diagnostic purposes.
|
||||
DynReturnFn,
|
||||
LatticeVariable,
|
||||
|
|
|
@ -285,7 +285,8 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
|
|||
let obligations =
|
||||
predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| {
|
||||
elaboratable.child_with_derived_cause(
|
||||
clause.subst_supertrait(tcx, &bound_clause.rebind(data.trait_ref)),
|
||||
clause
|
||||
.instantiate_supertrait(tcx, &bound_clause.rebind(data.trait_ref)),
|
||||
span,
|
||||
bound_clause.rebind(data),
|
||||
index,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue