Rollup merge of #120958 - ShoyuVanilla:remove-subst, r=oli-obk
Dejargonize `subst` In favor of #110793, replace almost every occurence of `subst` and `substitution` from rustc codes, but they still remains in subtrees under `src/tools/` like clippy and test codes (I'd like to replace them after this)
This commit is contained in:
commit
cb0d74be28
130 changed files with 576 additions and 543 deletions
|
@ -576,7 +576,7 @@ pub(in crate::solve) fn predicates_for_object_candidate<'tcx>(
|
|||
assert_eq!(
|
||||
old_ty,
|
||||
None,
|
||||
"{} has two substitutions: {} and {}",
|
||||
"{} has two generic parameters: {} and {}",
|
||||
proj.projection_ty,
|
||||
proj.term,
|
||||
old_ty.unwrap()
|
||||
|
|
|
@ -192,11 +192,14 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
original_values: Vec<ty::GenericArg<'tcx>>,
|
||||
response: CanonicalResponse<'tcx>,
|
||||
) -> Result<(Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution> {
|
||||
let substitution =
|
||||
Self::compute_query_response_substitution(self.infcx, &original_values, &response);
|
||||
let instantiation = Self::compute_query_response_instantiation_values(
|
||||
self.infcx,
|
||||
&original_values,
|
||||
&response,
|
||||
);
|
||||
|
||||
let Response { var_values, external_constraints, certainty } =
|
||||
response.substitute(self.tcx(), &substitution);
|
||||
response.instantiate(self.tcx(), &instantiation);
|
||||
|
||||
let nested_goals =
|
||||
Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values)?;
|
||||
|
@ -209,10 +212,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
Ok((certainty, nested_goals))
|
||||
}
|
||||
|
||||
/// This returns the substitutions to instantiate the bound variables of
|
||||
/// This returns the canoncial variable values to instantiate the bound variables of
|
||||
/// the canonical response. This depends on the `original_values` for the
|
||||
/// bound variables.
|
||||
fn compute_query_response_substitution<T: ResponseT<'tcx>>(
|
||||
fn compute_query_response_instantiation_values<T: ResponseT<'tcx>>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
original_values: &[ty::GenericArg<'tcx>],
|
||||
response: &Canonical<'tcx, T>,
|
||||
|
@ -369,10 +372,10 @@ impl<'tcx> inspect::ProofTreeBuilder<'tcx> {
|
|||
original_values: &[ty::GenericArg<'tcx>],
|
||||
state: inspect::CanonicalState<'tcx, T>,
|
||||
) -> Result<(Vec<Goal<'tcx, ty::Predicate<'tcx>>>, T), NoSolution> {
|
||||
let substitution =
|
||||
EvalCtxt::compute_query_response_substitution(infcx, original_values, &state);
|
||||
let instantiation =
|
||||
EvalCtxt::compute_query_response_instantiation_values(infcx, original_values, &state);
|
||||
|
||||
let inspect::State { var_values, data } = state.substitute(infcx.tcx, &substitution);
|
||||
let inspect::State { var_values, data } = state.instantiate(infcx.tcx, &instantiation);
|
||||
|
||||
let nested_goals =
|
||||
EvalCtxt::unify_query_var_values(infcx, param_env, original_values, var_values)?;
|
||||
|
|
|
@ -312,8 +312,8 @@ fn rematch_unsize<'tcx>(
|
|||
let a_tail_ty = tail_field_ty.instantiate(tcx, a_args);
|
||||
let b_tail_ty = tail_field_ty.instantiate(tcx, b_args);
|
||||
|
||||
// Substitute just the unsizing params from B into A. The type after
|
||||
// this substitution must be equal to B. This is so we don't unsize
|
||||
// Instantiate just the unsizing params from B into A. The type after
|
||||
// this instantiation must be equal to B. This is so we don't unsize
|
||||
// unrelated type parameters.
|
||||
let new_a_args = tcx.mk_args_from_iter(
|
||||
a_args
|
||||
|
@ -349,7 +349,7 @@ fn rematch_unsize<'tcx>(
|
|||
let (a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
|
||||
let b_last_ty = b_tys.last().unwrap();
|
||||
|
||||
// Substitute just the tail field of B., and require that they're equal.
|
||||
// Instantiate just the tail field of B., and require that they're equal.
|
||||
let unsized_a_ty =
|
||||
Ty::new_tup_from_iter(tcx, a_rest_tys.iter().chain([b_last_ty]).copied());
|
||||
nested.extend(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Computes a normalizes-to (projection) goal for inherent associated types,
|
||||
//! `#![feature(inherent_associated_type)]`. Since astconv already determines
|
||||
//! which impl the IAT is being projected from, we just:
|
||||
//! 1. instantiate substs,
|
||||
//! 1. instantiate generic parameters,
|
||||
//! 2. equate the self type, and
|
||||
//! 3. instantiate and register where clauses.
|
||||
use rustc_middle::traits::solve::{Certainty, Goal, GoalSource, QueryResult};
|
||||
|
@ -19,21 +19,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
let expected = goal.predicate.term.ty().expect("inherent consts are treated separately");
|
||||
|
||||
let impl_def_id = tcx.parent(inherent.def_id);
|
||||
let impl_substs = self.fresh_args_for_item(impl_def_id);
|
||||
let impl_args = self.fresh_args_for_item(impl_def_id);
|
||||
|
||||
// Equate impl header and add impl where clauses
|
||||
self.eq(
|
||||
goal.param_env,
|
||||
inherent.self_ty(),
|
||||
tcx.type_of(impl_def_id).instantiate(tcx, impl_substs),
|
||||
tcx.type_of(impl_def_id).instantiate(tcx, impl_args),
|
||||
)?;
|
||||
|
||||
// Equate IAT with the RHS of the project goal
|
||||
let inherent_substs = inherent.rebase_inherent_args_onto_impl(impl_substs, tcx);
|
||||
let inherent_args = inherent.rebase_inherent_args_onto_impl(impl_args, tcx);
|
||||
self.eq(
|
||||
goal.param_env,
|
||||
expected,
|
||||
tcx.type_of(inherent.def_id).instantiate(tcx, inherent_substs),
|
||||
tcx.type_of(inherent.def_id).instantiate(tcx, inherent_args),
|
||||
)
|
||||
.expect("expected goal term to be fully unconstrained");
|
||||
|
||||
|
@ -46,7 +46,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
self.add_goals(
|
||||
GoalSource::Misc,
|
||||
tcx.predicates_of(inherent.def_id)
|
||||
.instantiate(tcx, inherent_substs)
|
||||
.instantiate(tcx, inherent_args)
|
||||
.into_iter()
|
||||
.map(|(pred, _)| goal.with(tcx, pred)),
|
||||
);
|
||||
|
|
|
@ -877,8 +877,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
let a_tail_ty = tail_field_ty.instantiate(tcx, a_args);
|
||||
let b_tail_ty = tail_field_ty.instantiate(tcx, b_args);
|
||||
|
||||
// Substitute just the unsizing params from B into A. The type after
|
||||
// this substitution must be equal to B. This is so we don't unsize
|
||||
// Instantiate just the unsizing params from B into A. The type after
|
||||
// this instantiation must be equal to B. This is so we don't unsize
|
||||
// unrelated type parameters.
|
||||
let new_a_args = tcx.mk_args_from_iter(
|
||||
a_args
|
||||
|
@ -927,7 +927,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
|
||||
let &b_last_ty = b_tys.last().unwrap();
|
||||
|
||||
// Substitute just the tail field of B., and require that they're equal.
|
||||
// Instantiate just the tail field of B., and require that they're equal.
|
||||
let unsized_a_ty =
|
||||
Ty::new_tup_from_iter(tcx, a_rest_tys.iter().copied().chain([b_last_ty]));
|
||||
self.eq(goal.param_env, unsized_a_ty, b_ty)?;
|
||||
|
|
|
@ -84,7 +84,7 @@ impl TrackAmbiguityCauses {
|
|||
|
||||
/// If there are types that satisfy both impls, returns `Some`
|
||||
/// with a suitably-freshened `ImplHeader` with those types
|
||||
/// substituted. Otherwise, returns `None`.
|
||||
/// instantiated. Otherwise, returns `None`.
|
||||
#[instrument(skip(tcx, skip_leak_check), level = "debug")]
|
||||
pub fn overlapping_impls(
|
||||
tcx: TyCtxt<'_>,
|
||||
|
@ -561,21 +561,21 @@ pub fn trait_ref_is_knowable<'tcx, E: Debug>(
|
|||
) -> Result<Result<(), Conflict>, E> {
|
||||
if orphan_check_trait_ref(trait_ref, InCrate::Remote, &mut lazily_normalize_ty)?.is_ok() {
|
||||
// A downstream or cousin crate is allowed to implement some
|
||||
// substitution of this trait-ref.
|
||||
// generic parameters of this trait-ref.
|
||||
return Ok(Err(Conflict::Downstream));
|
||||
}
|
||||
|
||||
if trait_ref_is_local_or_fundamental(tcx, trait_ref) {
|
||||
// This is a local or fundamental trait, so future-compatibility
|
||||
// is no concern. We know that downstream/cousin crates are not
|
||||
// allowed to implement a substitution of this trait ref, which
|
||||
// means impls could only come from dependencies of this crate,
|
||||
// which we already know about.
|
||||
// allowed to implement a generic parameter of this trait ref,
|
||||
// which means impls could only come from dependencies of this
|
||||
// crate, which we already know about.
|
||||
return Ok(Ok(()));
|
||||
}
|
||||
|
||||
// This is a remote non-fundamental trait, so if another crate
|
||||
// can be the "final owner" of a substitution of this trait-ref,
|
||||
// can be the "final owner" of the generic parameters of this trait-ref,
|
||||
// they are allowed to implement it future-compatibly.
|
||||
//
|
||||
// However, if we are a final owner, then nobody else can be,
|
||||
|
@ -628,8 +628,8 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
|
|||
///
|
||||
/// The current rule is that a trait-ref orphan checks in a crate C:
|
||||
///
|
||||
/// 1. Order the parameters in the trait-ref in subst order - Self first,
|
||||
/// others linearly (e.g., `<U as Foo<V, W>>` is U < V < W).
|
||||
/// 1. Order the parameters in the trait-ref in generic parameters order
|
||||
/// - Self first, others linearly (e.g., `<U as Foo<V, W>>` is U < V < W).
|
||||
/// 2. Of these type parameters, there is at least one type parameter
|
||||
/// in which, walking the type as a tree, you can reach a type local
|
||||
/// to C where all types in-between are fundamental types. Call the
|
||||
|
@ -696,7 +696,7 @@ pub fn orphan_check(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Result<(), OrphanChe
|
|||
///
|
||||
/// Because we never perform negative reasoning generically (coherence does
|
||||
/// not involve type parameters), this can be interpreted as doing the full
|
||||
/// orphan check (using InCrate::Local mode), substituting non-local known
|
||||
/// orphan check (using InCrate::Local mode), instantiating non-local known
|
||||
/// types for all inference variables.
|
||||
///
|
||||
/// This allows for crates to future-compatibly add impls as long as they
|
||||
|
|
|
@ -242,7 +242,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
|||
self.tcx.lang_items().fn_once_trait(),
|
||||
] {
|
||||
let Some(trait_def_id) = trait_def_id else { continue };
|
||||
// Make a fresh inference variable so we can determine what the substitutions
|
||||
// Make a fresh inference variable so we can determine what the generic parameters
|
||||
// of the trait are.
|
||||
let var = self.next_ty_var(TypeVariableOrigin {
|
||||
span: DUMMY_SP,
|
||||
|
|
|
@ -814,7 +814,7 @@ impl<'tcx> OnUnimplementedFormatString {
|
|||
tcx.dcx(),
|
||||
self.span,
|
||||
E0231,
|
||||
"only named substitution parameters are allowed"
|
||||
"only named generic parameters are allowed"
|
||||
)
|
||||
.emit();
|
||||
result = Err(reported);
|
||||
|
|
|
@ -635,7 +635,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
| hir::Node::ImplItem(hir::ImplItem { generics, .. })
|
||||
if param_ty =>
|
||||
{
|
||||
// We skip the 0'th subst (self) because we do not want
|
||||
// We skip the 0'th arg (self) because we do not want
|
||||
// to consider the predicate as not suggestible if the
|
||||
// self type is an arg position `impl Trait` -- instead,
|
||||
// we handle that by adding ` + Bound` below.
|
||||
|
@ -2343,7 +2343,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
err: &mut DiagnosticBuilder<'tcx>,
|
||||
) {
|
||||
// First, look for an `ExprBindingObligation`, which means we can get
|
||||
// the unsubstituted predicate list of the called function. And check
|
||||
// the uninstantiated predicate list of the called function. And check
|
||||
// that the predicate that we failed to satisfy is a `Fn`-like trait.
|
||||
if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = cause
|
||||
&& let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
|
||||
|
|
|
@ -2422,16 +2422,16 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
// known, since we don't dispatch based on region
|
||||
// relationships.
|
||||
|
||||
// Pick the first substitution that still contains inference variables as the one
|
||||
// Pick the first generic parameter that still contains inference variables as the one
|
||||
// we're going to emit an error for. If there are none (see above), fall back to
|
||||
// a more general error.
|
||||
let subst = data.trait_ref.args.iter().find(|s| s.has_non_region_infer());
|
||||
let arg = data.trait_ref.args.iter().find(|s| s.has_non_region_infer());
|
||||
|
||||
let mut err = if let Some(subst) = subst {
|
||||
let mut err = if let Some(arg) = arg {
|
||||
self.emit_inference_failure_err(
|
||||
obligation.cause.body_id,
|
||||
span,
|
||||
subst,
|
||||
arg,
|
||||
ErrorCode::E0283,
|
||||
true,
|
||||
)
|
||||
|
@ -2469,9 +2469,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
}
|
||||
if ambiguities.len() > 1 && ambiguities.len() < 10 && has_non_region_infer {
|
||||
if let Some(e) = self.tainted_by_errors()
|
||||
&& subst.is_none()
|
||||
&& arg.is_none()
|
||||
{
|
||||
// If `subst.is_none()`, then this is probably two param-env
|
||||
// If `arg.is_none()`, then this is probably two param-env
|
||||
// candidates or impl candidates that are equal modulo lifetimes.
|
||||
// Therefore, if we've already emitted an error, just skip this
|
||||
// one, since it's not particularly actionable.
|
||||
|
@ -2505,7 +2505,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
|
||||
}
|
||||
|
||||
if let Some(ty::GenericArgKind::Type(_)) = subst.map(|subst| subst.unpack())
|
||||
if let Some(ty::GenericArgKind::Type(_)) = arg.map(|arg| arg.unpack())
|
||||
&& let Some(body_id) =
|
||||
self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id)
|
||||
{
|
||||
|
@ -2683,23 +2683,23 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
// other `Foo` impls are incoherent.
|
||||
return guar;
|
||||
}
|
||||
let subst = data
|
||||
let arg = data
|
||||
.projection_ty
|
||||
.args
|
||||
.iter()
|
||||
.chain(Some(data.term.into_arg()))
|
||||
.find(|g| g.has_non_region_infer());
|
||||
if let Some(subst) = subst {
|
||||
if let Some(arg) = arg {
|
||||
self.emit_inference_failure_err(
|
||||
obligation.cause.body_id,
|
||||
span,
|
||||
subst,
|
||||
arg,
|
||||
ErrorCode::E0284,
|
||||
true,
|
||||
)
|
||||
.with_note(format!("cannot satisfy `{predicate}`"))
|
||||
} else {
|
||||
// If we can't find a substitution, just print a generic error
|
||||
// If we can't find a generic parameter, just print a generic error
|
||||
struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
|
@ -2718,18 +2718,18 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||
if let Some(e) = self.tainted_by_errors() {
|
||||
return e;
|
||||
}
|
||||
let subst = data.walk().find(|g| g.is_non_region_infer());
|
||||
if let Some(subst) = subst {
|
||||
let arg = data.walk().find(|g| g.is_non_region_infer());
|
||||
if let Some(arg) = arg {
|
||||
let err = self.emit_inference_failure_err(
|
||||
obligation.cause.body_id,
|
||||
span,
|
||||
subst,
|
||||
arg,
|
||||
ErrorCode::E0284,
|
||||
true,
|
||||
);
|
||||
err
|
||||
} else {
|
||||
// If we can't find a substitution, just print a generic error
|
||||
// If we can't find a generic parameter, just print a generic error
|
||||
struct_span_code_err!(
|
||||
self.dcx(),
|
||||
span,
|
||||
|
|
|
@ -443,11 +443,11 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
|
|||
result
|
||||
}
|
||||
|
||||
fn subst_and_check_impossible_predicates<'tcx>(
|
||||
fn instantiate_and_check_impossible_predicates<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: (DefId, GenericArgsRef<'tcx>),
|
||||
) -> bool {
|
||||
debug!("subst_and_check_impossible_predicates(key={:?})", key);
|
||||
debug!("instantiate_and_check_impossible_predicates(key={:?})", key);
|
||||
|
||||
let mut predicates = tcx.predicates_of(key.0).instantiate(tcx, key.1).predicates;
|
||||
|
||||
|
@ -461,7 +461,7 @@ fn subst_and_check_impossible_predicates<'tcx>(
|
|||
predicates.retain(|predicate| !predicate.has_param());
|
||||
let result = impossible_predicates(tcx, predicates);
|
||||
|
||||
debug!("subst_and_check_impossible_predicates(key={:?}) = {:?}", key, result);
|
||||
debug!("instantiate_and_check_impossible_predicates(key={:?}) = {:?}", key, result);
|
||||
result
|
||||
}
|
||||
|
||||
|
@ -548,7 +548,7 @@ pub fn provide(providers: &mut Providers) {
|
|||
*providers = Providers {
|
||||
specialization_graph_of: specialize::specialization_graph_provider,
|
||||
specializes: specialize::specializes,
|
||||
subst_and_check_impossible_predicates,
|
||||
instantiate_and_check_impossible_predicates,
|
||||
check_tys_might_be_eq: misc::check_tys_might_be_eq,
|
||||
is_impossible_associated_item,
|
||||
..*providers
|
||||
|
|
|
@ -263,7 +263,7 @@ fn predicates_reference_self(
|
|||
predicates
|
||||
.predicates
|
||||
.iter()
|
||||
.map(|&(predicate, sp)| (predicate.subst_supertrait(tcx, &trait_ref), sp))
|
||||
.map(|&(predicate, sp)| (predicate.instantiate_supertrait(tcx, &trait_ref), sp))
|
||||
.filter_map(|predicate| predicate_references_self(tcx, predicate))
|
||||
.collect()
|
||||
}
|
||||
|
@ -607,7 +607,7 @@ fn virtual_call_violations_for_method<'tcx>(
|
|||
errors
|
||||
}
|
||||
|
||||
/// Performs a type substitution to produce the version of `receiver_ty` when `Self = self_ty`.
|
||||
/// Performs a type instantiation to produce the version of `receiver_ty` when `Self = self_ty`.
|
||||
/// For example, for `receiver_ty = Rc<Self>` and `self_ty = Foo`, returns `Rc<Foo>`.
|
||||
fn receiver_for_self_ty<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -682,7 +682,7 @@ fn object_ty_for_trait<'tcx>(
|
|||
/// ```
|
||||
///
|
||||
/// where `Foo[X => Y]` means "the same type as `Foo`, but with `X` replaced with `Y`"
|
||||
/// (substitution notation).
|
||||
/// (instantiation notation).
|
||||
///
|
||||
/// Some examples of receiver types and their required obligation:
|
||||
/// - `&'a mut self` requires `&'a mut Self: DispatchFromDyn<&'a mut dyn Trait>`,
|
||||
|
|
|
@ -266,7 +266,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
|
|||
// universe just created. Otherwise, we can end up with something like `for<'a> I: 'a`,
|
||||
// which isn't quite what we want. Ideally, we want either an implied
|
||||
// `for<'a where I: 'a> I: 'a` or we want to "lazily" check these hold when we
|
||||
// substitute concrete regions. There is design work to be done here; until then,
|
||||
// instantiate concrete regions. There is design work to be done here; until then,
|
||||
// however, this allows experimenting potential GAT features without running into
|
||||
// well-formedness issues.
|
||||
let new_obligations = obligations
|
||||
|
@ -1115,7 +1115,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
|
|||
/// as Trait>::Item`. The result is always a type (and possibly
|
||||
/// additional obligations). If ambiguity arises, which implies that
|
||||
/// there are unresolved type variables in the projection, we will
|
||||
/// substitute a fresh type variable `$X` and generate a new
|
||||
/// instantiate it with a fresh type variable `$X` and generate a new
|
||||
/// obligation `<T as Trait>::Item == $X` for later.
|
||||
pub fn normalize_projection_type<'a, 'b, 'tcx>(
|
||||
selcx: &'a mut SelectionContext<'b, 'tcx>,
|
||||
|
@ -1400,7 +1400,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
|
|||
cause.span,
|
||||
cause.body_id,
|
||||
// FIXME(inherent_associated_types): Since we can't pass along the self type to the
|
||||
// cause code, inherent projections will be printed with identity substitutions in
|
||||
// cause code, inherent projections will be printed with identity instantiation in
|
||||
// diagnostics which is not ideal.
|
||||
// Consider creating separate cause codes for this specific situation.
|
||||
if span.is_dummy() {
|
||||
|
|
|
@ -116,7 +116,7 @@ fn relate_mir_and_user_args<'tcx>(
|
|||
ocx.register_obligation(Obligation::new(tcx, cause, param_env, instantiated_predicate));
|
||||
}
|
||||
|
||||
// Now prove the well-formedness of `def_id` with `substs`.
|
||||
// Now prove the well-formedness of `def_id` with `args`.
|
||||
// Note for some items, proving the WF of `ty` is not sufficient because the
|
||||
// well-formedness of an item may depend on the WF of gneneric args not present in the
|
||||
// item's type. Currently this is true for associated consts, e.g.:
|
||||
|
|
|
@ -170,7 +170,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
|
|||
}
|
||||
|
||||
// Compute the obligations for `arg` to be well-formed. If `arg` is
|
||||
// an unresolved inference variable, just substituted an empty set
|
||||
// an unresolved inference variable, just instantiated an empty set
|
||||
// -- because the return type here is going to be things we *add*
|
||||
// to the environment, it's always ok for this set to be smaller
|
||||
// than the ultimate set. (Note: normally there won't be
|
||||
|
|
|
@ -557,7 +557,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
obligation.predicate.def_id(),
|
||||
obligation.predicate.skip_binder().trait_ref.self_ty(),
|
||||
|impl_def_id| {
|
||||
// Before we create the substitutions and everything, first
|
||||
// Before we create the generic parameters and everything, first
|
||||
// consider a "quick reject". This avoids creating more types
|
||||
// and so forth that we need to.
|
||||
let impl_trait_ref = self.tcx().impl_trait_ref(impl_def_id).unwrap();
|
||||
|
|
|
@ -444,7 +444,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
) -> ImplSourceUserDefinedData<'tcx, PredicateObligation<'tcx>> {
|
||||
debug!(?obligation, ?impl_def_id, "confirm_impl_candidate");
|
||||
|
||||
// First, create the substitutions by matching the impl again,
|
||||
// First, create the generic parameters by matching the impl again,
|
||||
// this time not in a probe.
|
||||
let args = self.rematch_impl(impl_def_id, obligation);
|
||||
debug!(?args, "impl args");
|
||||
|
@ -585,7 +585,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
// higher-ranked things.
|
||||
// Prevent, e.g., `dyn Iterator<Item = str>`.
|
||||
for bound in self.tcx().item_bounds(assoc_type).transpose_iter() {
|
||||
let subst_bound = if defs.count() == 0 {
|
||||
let arg_bound = if defs.count() == 0 {
|
||||
bound.instantiate(tcx, trait_predicate.trait_ref.args)
|
||||
} else {
|
||||
let mut args = smallvec::SmallVec::with_capacity(defs.count());
|
||||
|
@ -649,7 +649,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
obligation.param_env,
|
||||
obligation.cause.clone(),
|
||||
obligation.recursion_depth + 1,
|
||||
subst_bound,
|
||||
arg_bound,
|
||||
&mut nested,
|
||||
);
|
||||
nested.push(obligation.with(tcx, normalized_bound));
|
||||
|
|
|
@ -1684,7 +1684,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
/// Return `Yes` if the obligation's predicate type applies to the env_predicate, and
|
||||
/// `No` if it does not. Return `Ambiguous` in the case that the projection type is a GAT,
|
||||
/// and applying this env_predicate constrains any of the obligation's GAT substitutions.
|
||||
/// and applying this env_predicate constrains any of the obligation's GAT parameters.
|
||||
///
|
||||
/// This behavior is a somewhat of a hack to prevent over-constraining inference variables
|
||||
/// in cases like #91762.
|
||||
|
@ -2681,7 +2681,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
}
|
||||
|
||||
/// Returns the obligations that are implied by instantiating an
|
||||
/// impl or trait. The obligations are substituted and fully
|
||||
/// impl or trait. The obligations are instantiated and fully
|
||||
/// normalized. This is used when confirming an impl or default
|
||||
/// impl.
|
||||
#[instrument(level = "debug", skip(self, cause, param_env))]
|
||||
|
@ -2706,7 +2706,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
|||
// U: Iterator, U: Sized,
|
||||
// V: Iterator, V: Sized,
|
||||
// <U as Iterator>::Item: Copy
|
||||
// When we substitute, say, `V => IntoIter<u32>, U => $0`, the last
|
||||
// When we instantiate, say, `V => IntoIter<u32>, U => $0`, the last
|
||||
// obligation will normalize to `<$0 as Iterator>::Item = $1` and
|
||||
// `$1: Copy`, so we must ensure the obligations are emitted in
|
||||
// that order.
|
||||
|
|
|
@ -41,17 +41,17 @@ pub struct OverlapError<'tcx> {
|
|||
pub involves_placeholder: bool,
|
||||
}
|
||||
|
||||
/// Given a subst for the requested impl, translate it to a subst
|
||||
/// Given the generic parameters for the requested impl, translate it to the generic parameters
|
||||
/// appropriate for the actual item definition (whether it be in that impl,
|
||||
/// a parent impl, or the trait).
|
||||
///
|
||||
/// When we have selected one impl, but are actually using item definitions from
|
||||
/// a parent impl providing a default, we need a way to translate between the
|
||||
/// type parameters of the two impls. Here the `source_impl` is the one we've
|
||||
/// selected, and `source_args` is a substitution of its generics.
|
||||
/// selected, and `source_args` is its generic parameters.
|
||||
/// And `target_node` is the impl/trait we're actually going to get the
|
||||
/// definition from. The resulting substitution will map from `target_node`'s
|
||||
/// generics to `source_impl`'s generics as instantiated by `source_subst`.
|
||||
/// definition from. The resulting instantiation will map from `target_node`'s
|
||||
/// generics to `source_impl`'s generics as instantiated by `source_args`.
|
||||
///
|
||||
/// For example, consider the following scenario:
|
||||
///
|
||||
|
@ -62,7 +62,7 @@ pub struct OverlapError<'tcx> {
|
|||
/// ```
|
||||
///
|
||||
/// Suppose we have selected "source impl" with `V` instantiated with `u32`.
|
||||
/// This function will produce a substitution with `T` and `U` both mapping to `u32`.
|
||||
/// This function will produce an instantiation with `T` and `U` both mapping to `u32`.
|
||||
///
|
||||
/// where-clauses add some trickiness here, because they can be used to "define"
|
||||
/// an argument indirectly:
|
||||
|
@ -72,7 +72,7 @@ pub struct OverlapError<'tcx> {
|
|||
/// where I: Iterator<Item = &'a T>, T: Clone
|
||||
/// ```
|
||||
///
|
||||
/// In a case like this, the substitution for `T` is determined indirectly,
|
||||
/// In a case like this, the instantiation for `T` is determined indirectly,
|
||||
/// through associated type projection. We deal with such cases by using
|
||||
/// *fulfillment* to relate the two impls, requiring that all projections are
|
||||
/// resolved.
|
||||
|
@ -109,7 +109,7 @@ pub fn translate_args_with_cause<'tcx>(
|
|||
let source_trait_ref =
|
||||
infcx.tcx.impl_trait_ref(source_impl).unwrap().instantiate(infcx.tcx, source_args);
|
||||
|
||||
// translate the Self and Param parts of the substitution, since those
|
||||
// translate the Self and Param parts of the generic parameters, since those
|
||||
// vary across impls
|
||||
let target_args = match target_node {
|
||||
specialization_graph::Node::Impl(target_impl) => {
|
||||
|
@ -121,8 +121,8 @@ pub fn translate_args_with_cause<'tcx>(
|
|||
fulfill_implication(infcx, param_env, source_trait_ref, source_impl, target_impl, cause)
|
||||
.unwrap_or_else(|()| {
|
||||
bug!(
|
||||
"When translating substitutions from {source_impl:?} to {target_impl:?}, \
|
||||
the expected specialization failed to hold"
|
||||
"When translating generic parameters from {source_impl:?} to \
|
||||
{target_impl:?}, the expected specialization failed to hold"
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
|
|||
}
|
||||
|
||||
/// Attempt to fulfill all obligations of `target_impl` after unification with
|
||||
/// `source_trait_ref`. If successful, returns a substitution for *all* the
|
||||
/// `source_trait_ref`. If successful, returns the generic parameters for *all* the
|
||||
/// generics of `target_impl`, including both those needed to unify with
|
||||
/// `source_trait_ref` and those whose identity is determined via a where
|
||||
/// clause in the impl.
|
||||
|
@ -247,7 +247,7 @@ fn fulfill_implication<'tcx>(
|
|||
};
|
||||
|
||||
// Needs to be `in_snapshot` because this function is used to rebase
|
||||
// substitutions, which may happen inside of a select within a probe.
|
||||
// generic parameters, which may happen inside of a select within a probe.
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
// attempt to prove all of the predicates for impl2 given those for impl1
|
||||
// (which are packed up in penv)
|
||||
|
@ -269,7 +269,7 @@ fn fulfill_implication<'tcx>(
|
|||
|
||||
debug!("fulfill_implication: an impl for {:?} specializes {:?}", source_trait, target_trait);
|
||||
|
||||
// Now resolve the *substitution* we built for the target earlier, replacing
|
||||
// Now resolve the *generic parameters* we built for the target earlier, replacing
|
||||
// the inference variables inside with whatever we got from fulfillment.
|
||||
Ok(infcx.resolve_vars_if_possible(target_args))
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
|
|||
debug!(?predicates);
|
||||
|
||||
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
|
||||
pred.subst_supertrait(tcx, &trait_ref)
|
||||
pred.instantiate_supertrait(tcx, &trait_ref)
|
||||
.as_trait_clause()
|
||||
.map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
|
||||
});
|
||||
|
|
|
@ -124,7 +124,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
|
|||
.predicates
|
||||
.into_iter()
|
||||
.filter_map(move |(pred, _)| {
|
||||
pred.subst_supertrait(tcx, &inner_most_trait_ref).as_trait_clause()
|
||||
pred.instantiate_supertrait(tcx, &inner_most_trait_ref).as_trait_clause()
|
||||
});
|
||||
|
||||
// Find an unvisited supertrait
|
||||
|
|
|
@ -380,7 +380,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
|||
.filter(|(_, arg)| !arg.has_escaping_bound_vars())
|
||||
.map(|(i, arg)| {
|
||||
let mut cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
// The first subst is the self ty - use the correct span for it.
|
||||
// The first arg is the self ty - use the correct span for it.
|
||||
if i == 0 {
|
||||
if let Some(hir::ItemKind::Impl(hir::Impl { self_ty, .. })) =
|
||||
item.map(|i| &i.kind)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue