Dejargnonize subst
This commit is contained in:
parent
084ce5bdb5
commit
3856df059e
128 changed files with 574 additions and 541 deletions
|
@ -53,7 +53,7 @@ impl<'tcx> ty::TypeFoldable<TyCtxt<'tcx>> for CanonicalVarInfos<'tcx> {
|
|||
|
||||
/// A set of values corresponding to the canonical variables from some
|
||||
/// `Canonical`. You can give these values to
|
||||
/// `canonical_value.substitute` to substitute them into the canonical
|
||||
/// `canonical_value.instantiate` to instantiate them into the canonical
|
||||
/// value at the right places.
|
||||
///
|
||||
/// When you canonicalize a value `V`, you get back one of these
|
||||
|
|
|
@ -11,13 +11,13 @@ use rustc_session::lint;
|
|||
use rustc_span::{Span, DUMMY_SP};
|
||||
|
||||
impl<'tcx> TyCtxt<'tcx> {
|
||||
/// Evaluates a constant without providing any substitutions. This is useful to evaluate consts
|
||||
/// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
|
||||
/// that can't take any generic arguments like statics, const items or enum discriminants. If a
|
||||
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn const_eval_poly(self, def_id: DefId) -> EvalToConstValueResult<'tcx> {
|
||||
// In some situations def_id will have substitutions within scope, but they aren't allowed
|
||||
// to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
|
||||
// In some situations def_id will have generic parameters within scope, but they aren't allowed
|
||||
// to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters
|
||||
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
|
||||
// encountered.
|
||||
let args = GenericArgs::identity_for_item(self, def_id);
|
||||
|
@ -29,10 +29,10 @@ impl<'tcx> TyCtxt<'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 generic parameters 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.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
|
@ -214,13 +214,13 @@ impl<'tcx> TyCtxtAt<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> TyCtxtEnsure<'tcx> {
|
||||
/// Evaluates a constant without providing any substitutions. This is useful to evaluate consts
|
||||
/// Evaluates a constant without providing any generic parameters. This is useful to evaluate consts
|
||||
/// that can't take any generic arguments like statics, const items or enum discriminants. If a
|
||||
/// generic parameter is used within the constant `ErrorHandled::ToGeneric` will be returned.
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn const_eval_poly(self, def_id: DefId) {
|
||||
// In some situations def_id will have substitutions within scope, but they aren't allowed
|
||||
// to be used. So we can't use `Instance::mono`, instead we feed unresolved substitutions
|
||||
// In some situations def_id will have generic parameters within scope, but they aren't allowed
|
||||
// to be used. So we can't use `Instance::mono`, instead we feed unresolved generic parameters
|
||||
// into `const_eval` which will return `ErrorHandled::ToGeneric` if any of them are
|
||||
// encountered.
|
||||
let args = GenericArgs::identity_for_item(self.tcx, def_id);
|
||||
|
|
|
@ -186,7 +186,7 @@ impl<'tcx> MonoItem<'tcx> {
|
|||
MonoItem::GlobalAsm(..) => return true,
|
||||
};
|
||||
|
||||
!tcx.subst_and_check_impossible_predicates((def_id, &args))
|
||||
!tcx.instantiate_and_check_impossible_predicates((def_id, &args))
|
||||
}
|
||||
|
||||
pub fn local_span(&self, tcx: TyCtxt<'tcx>) -> Option<Span> {
|
||||
|
|
|
@ -2078,9 +2078,9 @@ rustc_queries! {
|
|||
desc { "normalizing `{:?}`", goal.value.value.value }
|
||||
}
|
||||
|
||||
query subst_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool {
|
||||
query instantiate_and_check_impossible_predicates(key: (DefId, GenericArgsRef<'tcx>)) -> bool {
|
||||
desc { |tcx|
|
||||
"checking impossible substituted predicates: `{}`",
|
||||
"checking impossible instantiated predicates: `{}`",
|
||||
tcx.def_path_str(key.0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -721,7 +721,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
|
|||
}
|
||||
|
||||
/// Identifies a particular impl in the source, along with a set of
|
||||
/// substitutions from the impl's type/lifetime parameters. The
|
||||
/// generic parameters from the impl's type/lifetime parameters. The
|
||||
/// `nested` vector corresponds to the nested obligations attached to
|
||||
/// the impl's type parameters.
|
||||
///
|
||||
|
|
|
@ -49,7 +49,8 @@ pub type EvaluationCache<'tcx> = Cache<
|
|||
/// parameters don't unify with regular types, but they *can* unify
|
||||
/// with variables from blanket impls, and (unless we know its bounds
|
||||
/// will always be satisfied) picking the blanket impl will be wrong
|
||||
/// for at least *some* substitutions. To make this concrete, if we have
|
||||
/// for at least *some* generic parameters. To make this concrete, if
|
||||
/// we have
|
||||
///
|
||||
/// ```rust, ignore
|
||||
/// trait AsDebug { type Out: fmt::Debug; fn debug(self) -> Self::Out; }
|
||||
|
|
|
@ -37,7 +37,7 @@ impl<'tcx> Elaborator<'tcx> {
|
|||
let super_predicates =
|
||||
self.tcx.super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map(
|
||||
|&(pred, _)| {
|
||||
let clause = pred.subst_supertrait(self.tcx, &trait_ref);
|
||||
let clause = pred.instantiate_supertrait(self.tcx, &trait_ref);
|
||||
self.visited.insert(clause).then_some(clause)
|
||||
},
|
||||
);
|
||||
|
|
|
@ -3,7 +3,7 @@ use crate::ty::relate::{self, Relate, RelateResult, TypeRelation};
|
|||
use crate::ty::{self, InferConst, Ty, TyCtxt};
|
||||
|
||||
/// A type "A" *matches* "B" if the fresh types in B could be
|
||||
/// substituted with values so as to make it equal to A. Matching is
|
||||
/// instantiated with values so as to make it equal to A. Matching is
|
||||
/// intended to be used only on freshened types, and it basically
|
||||
/// indicates if the non-freshened versions of A and B could have been
|
||||
/// unified.
|
||||
|
|
|
@ -235,7 +235,7 @@ impl<'tcx> Const<'tcx> {
|
|||
// FIXME(const_generics): We currently have to special case parameters because `min_const_generics`
|
||||
// does not provide the parents generics to anonymous constants. We still allow generic const
|
||||
// parameters by themselves however, e.g. `N`. These constants would cause an ICE if we were to
|
||||
// ever try to substitute the generic parameters in their bodies.
|
||||
// ever try to instantiate the generic parameters in their bodies.
|
||||
match expr.kind {
|
||||
hir::ExprKind::Path(hir::QPath::Resolved(
|
||||
_,
|
||||
|
|
|
@ -418,10 +418,10 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
// Shifter
|
||||
//
|
||||
// Shifts the De Bruijn indices on all escaping bound vars by a
|
||||
// fixed amount. Useful in substitution or when otherwise introducing
|
||||
// fixed amount. Useful in instantiation or when otherwise introducing
|
||||
// a binding level that is not intended to capture the existing bound
|
||||
// vars. See comment on `shift_vars_through_binders` method in
|
||||
// `subst.rs` for more details.
|
||||
// `rustc_middle/src/ty/generic_args.rs` for more details.
|
||||
|
||||
struct Shifter<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
|
|
@ -803,13 +803,13 @@ impl<'tcx, T: TypeFoldable<TyCtxt<'tcx>>> ty::EarlyBinder<T> {
|
|||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// The actual substitution engine itself is a type folder.
|
||||
// The actual instantiation engine itself is a type folder.
|
||||
|
||||
struct ArgFolder<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
args: &'a [GenericArg<'tcx>],
|
||||
|
||||
/// Number of region binders we have passed through while doing the substitution
|
||||
/// Number of region binders we have passed through while doing the instantiation
|
||||
binders_passed: u32,
|
||||
}
|
||||
|
||||
|
@ -834,7 +834,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> {
|
|||
#[inline(never)]
|
||||
fn region_param_out_of_range(data: ty::EarlyParamRegion, args: &[GenericArg<'_>]) -> ! {
|
||||
bug!(
|
||||
"Region parameter out of range when substituting in region {} (index={}, args = {:?})",
|
||||
"Region parameter out of range when instantiating in region {} (index={}, args = {:?})",
|
||||
data.name,
|
||||
data.index,
|
||||
args,
|
||||
|
@ -845,7 +845,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> {
|
|||
#[inline(never)]
|
||||
fn region_param_invalid(data: ty::EarlyParamRegion, other: GenericArgKind<'_>) -> ! {
|
||||
bug!(
|
||||
"Unexpected parameter {:?} when substituting in region {} (index={})",
|
||||
"Unexpected parameter {:?} when instantiating in region {} (index={})",
|
||||
other,
|
||||
data.name,
|
||||
data.index
|
||||
|
@ -854,7 +854,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ArgFolder<'a, 'tcx> {
|
|||
|
||||
// Note: This routine only handles regions that are bound on
|
||||
// type declarations and other outer declarations, not those
|
||||
// bound in *fn types*. Region substitution of the bound
|
||||
// bound in *fn types*. Region instantiation of the bound
|
||||
// regions that appear in a function signature is done using
|
||||
// the specialized routine `ty::replace_late_regions()`.
|
||||
match *r {
|
||||
|
@ -913,7 +913,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> {
|
|||
#[inline(never)]
|
||||
fn type_param_expected(&self, p: ty::ParamTy, ty: Ty<'tcx>, kind: GenericArgKind<'tcx>) -> ! {
|
||||
bug!(
|
||||
"expected type for `{:?}` ({:?}/{}) but found {:?} when substituting, args={:?}",
|
||||
"expected type for `{:?}` ({:?}/{}) but found {:?} when instantiating, args={:?}",
|
||||
p,
|
||||
ty,
|
||||
p.index,
|
||||
|
@ -926,7 +926,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> {
|
|||
#[inline(never)]
|
||||
fn type_param_out_of_range(&self, p: ty::ParamTy, ty: Ty<'tcx>) -> ! {
|
||||
bug!(
|
||||
"type parameter `{:?}` ({:?}/{}) out of range when substituting, args={:?}",
|
||||
"type parameter `{:?}` ({:?}/{}) out of range when instantiating, args={:?}",
|
||||
p,
|
||||
ty,
|
||||
p.index,
|
||||
|
@ -955,7 +955,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> {
|
|||
kind: GenericArgKind<'tcx>,
|
||||
) -> ! {
|
||||
bug!(
|
||||
"expected const for `{:?}` ({:?}/{}) but found {:?} when substituting args={:?}",
|
||||
"expected const for `{:?}` ({:?}/{}) but found {:?} when instantiating args={:?}",
|
||||
p,
|
||||
ct,
|
||||
p.index,
|
||||
|
@ -968,7 +968,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> {
|
|||
#[inline(never)]
|
||||
fn const_param_out_of_range(&self, p: ty::ParamConst, ct: ty::Const<'tcx>) -> ! {
|
||||
bug!(
|
||||
"const parameter `{:?}` ({:?}/{}) out of range when substituting args={:?}",
|
||||
"const parameter `{:?}` ({:?}/{}) out of range when instantiating args={:?}",
|
||||
p,
|
||||
ct,
|
||||
p.index,
|
||||
|
@ -976,8 +976,8 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> {
|
|||
)
|
||||
}
|
||||
|
||||
/// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs
|
||||
/// when we are substituting a type with escaping bound vars into a context where we have
|
||||
/// It is sometimes necessary to adjust the De Bruijn indices during instantiation. This occurs
|
||||
/// when we are instantating a type with escaping bound vars into a context where we have
|
||||
/// passed through binders. That's quite a mouthful. Let's see an example:
|
||||
///
|
||||
/// ```
|
||||
|
@ -997,7 +997,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> {
|
|||
/// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip
|
||||
/// over the inner binder (remember that we count De Bruijn indices from 1). However, in the
|
||||
/// definition of `MetaFunc`, the binder is not visible, so the type `&'a i32` will have a
|
||||
/// De Bruijn index of 1. It's only during the substitution that we can see we must increase the
|
||||
/// De Bruijn index of 1. It's only during the instantiation that we can see we must increase the
|
||||
/// depth by 1 to account for the binder that we passed through.
|
||||
///
|
||||
/// As a second example, consider this twist:
|
||||
|
@ -1015,7 +1015,7 @@ impl<'a, 'tcx> ArgFolder<'a, 'tcx> {
|
|||
/// // DebruijnIndex of 1 |
|
||||
/// // DebruijnIndex of 2
|
||||
/// ```
|
||||
/// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the
|
||||
/// As indicated in the diagram, here the same type `&'a i32` is instantiated once, but in the
|
||||
/// first case we do not increase the De Bruijn index and in the second case we do. The reason
|
||||
/// is that only in the second case have we passed through a fn binder.
|
||||
fn shift_vars_through_binders<T: TypeFoldable<TyCtxt<'tcx>>>(&self, val: T) -> T {
|
||||
|
|
|
@ -125,7 +125,7 @@ pub struct GenericParamCount {
|
|||
/// Information about the formal type/lifetime parameters associated
|
||||
/// with an item or method. Analogous to `hir::Generics`.
|
||||
///
|
||||
/// The ordering of parameters is the same as in `Subst` (excluding child generics):
|
||||
/// The ordering of parameters is the same as in [`ty::GenericArg`] (excluding child generics):
|
||||
/// `Self` (optionally), `Lifetime` params..., `Type` params...
|
||||
#[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
pub struct Generics {
|
||||
|
@ -140,7 +140,7 @@ pub struct Generics {
|
|||
pub has_self: bool,
|
||||
pub has_late_bound_regions: Option<Span>,
|
||||
|
||||
// The index of the host effect when substituted. (i.e. might be index to parent args)
|
||||
// The index of the host effect when instantiated. (i.e. might be index to parent args)
|
||||
pub host_effect_index: Option<usize>,
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ use std::fmt;
|
|||
///
|
||||
/// Monomorphization happens on-the-fly and no monomorphized MIR is ever created. Instead, this type
|
||||
/// simply couples a potentially generic `InstanceDef` with some args, and codegen and const eval
|
||||
/// will do all required substitution as they run.
|
||||
/// will do all required instantiations as they run.
|
||||
///
|
||||
/// Note: the `Lift` impl is currently not used by rustc, but is used by
|
||||
/// rustc_codegen_cranelift when the `jit` feature is enabled.
|
||||
|
@ -138,7 +138,7 @@ pub enum InstanceDef<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Instance<'tcx> {
|
||||
/// Returns the `Ty` corresponding to this `Instance`, with generic substitutions applied and
|
||||
/// Returns the `Ty` corresponding to this `Instance`, with generic instantiations applied and
|
||||
/// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization.
|
||||
pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
|
||||
let ty = tcx.type_of(self.def.def_id());
|
||||
|
@ -298,11 +298,11 @@ impl<'tcx> InstanceDef<'tcx> {
|
|||
}
|
||||
|
||||
/// Returns `true` when the MIR body associated with this instance should be monomorphized
|
||||
/// by its users (e.g. codegen or miri) by substituting the `args` from `Instance` (see
|
||||
/// by its users (e.g. codegen or miri) by instantiating the `args` from `Instance` (see
|
||||
/// `Instance::args_for_mir_body`).
|
||||
///
|
||||
/// Otherwise, returns `false` only for some kinds of shims where the construction of the MIR
|
||||
/// body should perform necessary substitutions.
|
||||
/// body should perform necessary instantiations.
|
||||
pub fn has_polymorphic_mir_body(&self) -> bool {
|
||||
match *self {
|
||||
InstanceDef::CloneShim(..)
|
||||
|
@ -672,13 +672,13 @@ impl<'tcx> Instance<'tcx> {
|
|||
|
||||
/// Depending on the kind of `InstanceDef`, the MIR body associated with an
|
||||
/// instance is expressed in terms of the generic parameters of `self.def_id()`, and in other
|
||||
/// cases the MIR body is expressed in terms of the types found in the substitution array.
|
||||
/// In the former case, we want to substitute those generic types and replace them with the
|
||||
/// cases the MIR body is expressed in terms of the types found in the generic parameter array.
|
||||
/// In the former case, we want to instantiate those generic types and replace them with the
|
||||
/// values from the args when monomorphizing the function body. But in the latter case, we
|
||||
/// don't want to do that substitution, since it has already been done effectively.
|
||||
/// don't want to do that instantiation, since it has already been done effectively.
|
||||
///
|
||||
/// This function returns `Some(args)` in the former case and `None` otherwise -- i.e., if
|
||||
/// this function returns `None`, then the MIR body does not require substitution during
|
||||
/// this function returns `None`, then the MIR body does not require instantiation during
|
||||
/// codegen.
|
||||
fn args_for_mir_body(&self) -> Option<GenericArgsRef<'tcx>> {
|
||||
self.def.has_polymorphic_mir_body().then_some(self.args)
|
||||
|
|
|
@ -728,7 +728,7 @@ impl From<ty::ConstVid> for TermVid {
|
|||
/// the `GenericPredicates` are expressed in terms of the bound type
|
||||
/// parameters of the impl/trait/whatever, an `InstantiatedPredicates` instance
|
||||
/// represented a set of bounds for some particular instantiation,
|
||||
/// meaning that the generic parameters have been substituted with
|
||||
/// meaning that the generic parameters have been instantiated with
|
||||
/// their values.
|
||||
///
|
||||
/// Example:
|
||||
|
@ -1654,7 +1654,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the possibly-auto-generated MIR of a `(DefId, Subst)` pair.
|
||||
/// Returns the possibly-auto-generated MIR of a [`ty::InstanceDef`].
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
pub fn instance_mir(self, instance: ty::InstanceDef<'tcx>) -> &'tcx Body<'tcx> {
|
||||
match instance {
|
||||
|
|
|
@ -135,7 +135,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
}
|
||||
|
||||
/// Monomorphizes a type from the AST by first applying the
|
||||
/// in-scope substitutions and then normalizing any associated
|
||||
/// in-scope instantiations and then normalizing any associated
|
||||
/// types.
|
||||
/// Panics if normalization fails. In case normalization might fail
|
||||
/// use `try_instantiate_and_normalize_erasing_regions` instead.
|
||||
|
@ -149,12 +149,12 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let substituted = value.instantiate(self, param_args);
|
||||
self.normalize_erasing_regions(param_env, substituted)
|
||||
let instantiated = value.instantiate(self, param_args);
|
||||
self.normalize_erasing_regions(param_env, instantiated)
|
||||
}
|
||||
|
||||
/// Monomorphizes a type from the AST by first applying the
|
||||
/// in-scope substitutions and then trying to normalize any associated
|
||||
/// in-scope instantiations and then trying to normalize any associated
|
||||
/// types. Contrary to `instantiate_and_normalize_erasing_regions` this does
|
||||
/// not assume that normalization succeeds.
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
|
@ -167,8 +167,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let substituted = value.instantiate(self, param_args);
|
||||
self.try_normalize_erasing_regions(param_env, substituted)
|
||||
let instantiated = value.instantiate(self, param_args);
|
||||
self.try_normalize_erasing_regions(param_env, instantiated)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -164,9 +164,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
|
|||
}
|
||||
|
||||
ty::Param(param) => {
|
||||
// Look it up in the substitution list.
|
||||
// Look it up in the generic parameters list.
|
||||
match self.map.get(&ty.into()).map(|k| k.unpack()) {
|
||||
// Found it in the substitution list; replace with the parameter from the
|
||||
// Found it in the generic parameters list; replace with the parameter from the
|
||||
// opaque type.
|
||||
Some(GenericArgKind::Type(t1)) => t1,
|
||||
Some(u) => panic!("type mapped to unexpected kind: {u:?}"),
|
||||
|
@ -199,9 +199,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
|
|||
// Find a const parameter
|
||||
match ct.kind() {
|
||||
ty::ConstKind::Param(..) => {
|
||||
// Look it up in the substitution list.
|
||||
// Look it up in the generic parameters list.
|
||||
match self.map.get(&ct.into()).map(|k| k.unpack()) {
|
||||
// Found it in the substitution list, replace with the parameter from the
|
||||
// Found it in the generic parameters list, replace with the parameter from the
|
||||
// opaque type.
|
||||
Some(GenericArgKind::Const(c1)) => c1,
|
||||
Some(u) => panic!("const mapped to unexpected kind: {u:?}"),
|
||||
|
|
|
@ -323,7 +323,7 @@ impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
|
|||
/// and `U` as parameter 1.
|
||||
///
|
||||
/// Trait references also appear in object types like `Foo<U>`, but in
|
||||
/// that case the `Self` parameter is absent from the substitutions.
|
||||
/// that case the `Self` parameter is absent from the generic parameters.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub struct TraitRef<'tcx> {
|
||||
|
@ -406,7 +406,7 @@ impl<'tcx> IntoDiagnosticArg for TraitRef<'tcx> {
|
|||
/// ```ignore (illustrative)
|
||||
/// exists T. T: Trait<'a, 'b, X, Y>
|
||||
/// ```
|
||||
/// The substitutions don't include the erased `Self`, only trait
|
||||
/// The generic parameters don't include the erased `Self`, only trait
|
||||
/// type and lifetime parameters (`[X, Y]` and `['a, 'b]` above).
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
|
@ -481,8 +481,8 @@ impl<'tcx> ExistentialProjection<'tcx> {
|
|||
/// reference.
|
||||
pub fn trait_ref(&self, tcx: TyCtxt<'tcx>) -> ty::ExistentialTraitRef<'tcx> {
|
||||
let def_id = tcx.parent(self.def_id);
|
||||
let subst_count = tcx.generics_of(def_id).count() - 1;
|
||||
let args = tcx.mk_args(&self.args[..subst_count]);
|
||||
let args_count = tcx.generics_of(def_id).count() - 1;
|
||||
let args = tcx.mk_args(&self.args[..args_count]);
|
||||
ty::ExistentialTraitRef { def_id, args }
|
||||
}
|
||||
|
||||
|
@ -534,12 +534,12 @@ impl<'tcx> PolyExistentialProjection<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Clause<'tcx> {
|
||||
/// Performs a substitution suitable for going from a
|
||||
/// Performs a instantiation suitable for going from a
|
||||
/// poly-trait-ref to supertraits that must hold if that
|
||||
/// poly-trait-ref holds. This is slightly different from a normal
|
||||
/// substitution in terms of what happens with bound regions. See
|
||||
/// instantiation in terms of what happens with bound regions. See
|
||||
/// lengthy comment below for details.
|
||||
pub fn subst_supertrait(
|
||||
pub fn instantiate_supertrait(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ref: &ty::PolyTraitRef<'tcx>,
|
||||
|
@ -556,7 +556,7 @@ impl<'tcx> Clause<'tcx> {
|
|||
// we can deduce that `for<'x> T: Bar<'x,'x>`. Basically, if we
|
||||
// knew that `Foo<'x>` (for any 'x) then we also know that
|
||||
// `Bar<'x,'x>` (for any 'x). This more-or-less falls out from
|
||||
// normal substitution.
|
||||
// normal instantiation.
|
||||
//
|
||||
// In terms of why this is sound, the idea is that whenever there
|
||||
// is an impl of `T:Foo<'a>`, it must show that `T:Bar<'a,'a>`
|
||||
|
@ -582,7 +582,7 @@ impl<'tcx> Clause<'tcx> {
|
|||
// - We start out with `for<'x> T: Foo1<'x>`. In this case, `'x`
|
||||
// has a De Bruijn index of 1. We want to produce `for<'x,'b> T: Bar1<'x,'b>`,
|
||||
// where both `'x` and `'b` would have a DB index of 1.
|
||||
// The substitution from the input trait-ref is therefore going to be
|
||||
// The instantiation from the input trait-ref is therefore going to be
|
||||
// `'a => 'x` (where `'x` has a DB index of 1).
|
||||
// - The supertrait-ref is `for<'b> Bar1<'a,'b>`, where `'a` is an
|
||||
// early-bound parameter and `'b` is a late-bound parameter with a
|
||||
|
@ -591,17 +591,17 @@ impl<'tcx> Clause<'tcx> {
|
|||
// a DB index of 1, and thus we'll have `for<'x,'b> Bar1<'x,'b>`
|
||||
// just as we wanted.
|
||||
//
|
||||
// There is only one catch. If we just apply the substitution `'a
|
||||
// => 'x` to `for<'b> Bar1<'a,'b>`, the substitution code will
|
||||
// adjust the DB index because we substituting into a binder (it
|
||||
// There is only one catch. If we just apply the instantiation `'a
|
||||
// => 'x` to `for<'b> Bar1<'a,'b>`, the instantiation code will
|
||||
// adjust the DB index because we instantiating into a binder (it
|
||||
// tries to be so smart...) resulting in `for<'x> for<'b>
|
||||
// Bar1<'x,'b>` (we have no syntax for this, so use your
|
||||
// imagination). Basically the 'x will have DB index of 2 and 'b
|
||||
// will have DB index of 1. Not quite what we want. So we apply
|
||||
// the substitution to the *contents* of the trait reference,
|
||||
// the instantiation to the *contents* of the trait reference,
|
||||
// rather than the trait reference itself (put another way, the
|
||||
// substitution code expects equal binding levels in the values
|
||||
// from the substitution and the value being substituted into, and
|
||||
// instantiation code expects equal binding levels in the values
|
||||
// from the instantiation and the value being instantiated into, and
|
||||
// this trick achieves that).
|
||||
|
||||
// Working through the second example:
|
||||
|
|
|
@ -208,7 +208,7 @@ impl<'tcx> ClosureArgs<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the substitutions of the closure's parent.
|
||||
/// Returns the generic parameters of the closure's parent.
|
||||
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
|
||||
self.split().parent_args
|
||||
}
|
||||
|
@ -615,7 +615,7 @@ impl<'tcx> CoroutineArgs<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the substitutions of the coroutine's parent.
|
||||
/// Returns the generic parameters of the coroutine's parent.
|
||||
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
|
||||
self.split().parent_args
|
||||
}
|
||||
|
@ -819,7 +819,7 @@ impl<'tcx> UpvarArgs<'tcx> {
|
|||
/// inherited from the item that defined the inline const,
|
||||
/// - R represents the type of the constant.
|
||||
///
|
||||
/// When the inline const is instantiated, `R` is substituted as the actual inferred
|
||||
/// When the inline const is instantiated, `R` is instantiated as the actual inferred
|
||||
/// type of the constant. The reason that `R` is represented as an extra type parameter
|
||||
/// is the same reason that [`ClosureArgs`] have `CS` and `U` as type parameters:
|
||||
/// inline const can reference lifetimes that are internal to the creating function.
|
||||
|
@ -858,7 +858,7 @@ impl<'tcx> InlineConstArgs<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the substitutions of the inline const's parent.
|
||||
/// Returns the generic parameters of the inline const's parent.
|
||||
pub fn parent_args(self) -> &'tcx [GenericArg<'tcx>] {
|
||||
self.split().parent_args
|
||||
}
|
||||
|
@ -1105,13 +1105,13 @@ where
|
|||
pub struct AliasTy<'tcx> {
|
||||
/// The parameters of the associated or opaque item.
|
||||
///
|
||||
/// For a projection, these are the substitutions for the trait and the
|
||||
/// GAT substitutions, if there are any.
|
||||
/// For a projection, these are the generic parameters for the trait and the
|
||||
/// GAT parameters, if there are any.
|
||||
///
|
||||
/// For an inherent projection, they consist of the self type and the GAT substitutions,
|
||||
/// For an inherent projection, they consist of the self type and the GAT parameters,
|
||||
/// if there are any.
|
||||
///
|
||||
/// For RPIT the substitutions are for the generics of the function,
|
||||
/// For RPIT the generic parameters are for the generics of the function,
|
||||
/// while for TAIT it is used for the generic parameters of the alias.
|
||||
pub args: GenericArgsRef<'tcx>,
|
||||
|
||||
|
@ -1235,15 +1235,15 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
|
||||
/// The following methods work only with inherent associated type projections.
|
||||
impl<'tcx> AliasTy<'tcx> {
|
||||
/// Transform the substitutions to have the given `impl` args as the base and the GAT args on top of that.
|
||||
/// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that.
|
||||
///
|
||||
/// Does the following transformation:
|
||||
///
|
||||
/// ```text
|
||||
/// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
|
||||
///
|
||||
/// I_i impl subst
|
||||
/// P_j GAT subst
|
||||
/// I_i impl args
|
||||
/// P_j GAT args
|
||||
/// ```
|
||||
pub fn rebase_inherent_args_onto_impl(
|
||||
self,
|
||||
|
@ -1690,7 +1690,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
debug_assert_eq!(
|
||||
closure_args.len(),
|
||||
tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 3,
|
||||
"closure constructed with incorrect substitutions"
|
||||
"closure constructed with incorrect generic parameters"
|
||||
);
|
||||
Ty::new(tcx, Closure(def_id, closure_args))
|
||||
}
|
||||
|
@ -1704,7 +1704,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
debug_assert_eq!(
|
||||
closure_args.len(),
|
||||
tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 5,
|
||||
"closure constructed with incorrect substitutions"
|
||||
"closure constructed with incorrect generic parameters"
|
||||
);
|
||||
Ty::new(tcx, CoroutineClosure(def_id, closure_args))
|
||||
}
|
||||
|
@ -1718,7 +1718,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
debug_assert_eq!(
|
||||
coroutine_args.len(),
|
||||
tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 6,
|
||||
"coroutine constructed with incorrect number of substitutions"
|
||||
"coroutine constructed with incorrect number of generic parameters"
|
||||
);
|
||||
Ty::new(tcx, Coroutine(def_id, coroutine_args))
|
||||
}
|
||||
|
@ -2530,7 +2530,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
}
|
||||
|
||||
/// Returns `true` when the outermost type cannot be further normalized,
|
||||
/// resolved, or substituted. This includes all primitive types, but also
|
||||
/// resolved, or instantiated. This includes all primitive types, but also
|
||||
/// things like ADTs and trait objects, sice even if their arguments or
|
||||
/// nested types may be further simplified, the outermost [`TyKind`] or
|
||||
/// type constructor remains the same.
|
||||
|
|
|
@ -49,19 +49,19 @@ pub struct TypeckResults<'tcx> {
|
|||
/// typeck::check::fn_ctxt for details.
|
||||
node_types: ItemLocalMap<Ty<'tcx>>,
|
||||
|
||||
/// Stores the type parameters which were substituted to obtain the type
|
||||
/// Stores the type parameters which were instantiated to obtain the type
|
||||
/// of this node. This only applies to nodes that refer to entities
|
||||
/// parameterized by type parameters, such as generic fns, types, or
|
||||
/// other items.
|
||||
node_args: ItemLocalMap<GenericArgsRef<'tcx>>,
|
||||
|
||||
/// This will either store the canonicalized types provided by the user
|
||||
/// or the substitutions that the user explicitly gave (if any) attached
|
||||
/// or the generic parameters that the user explicitly gave (if any) attached
|
||||
/// to `id`. These will not include any inferred values. The canonical form
|
||||
/// is used to capture things like `_` or other unspecified values.
|
||||
///
|
||||
/// For example, if the user wrote `foo.collect::<Vec<_>>()`, then the
|
||||
/// canonical substitutions would include only `for<X> { Vec<X> }`.
|
||||
/// canonical generic parameters would include only `for<X> { Vec<X> }`.
|
||||
///
|
||||
/// See also `AscribeUserType` statement in MIR.
|
||||
user_provided_types: ItemLocalMap<CanonicalUserType<'tcx>>,
|
||||
|
@ -329,7 +329,7 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
}
|
||||
|
||||
/// Returns the type of a pattern as a monotype. Like [`expr_ty`], this function
|
||||
/// doesn't provide type parameter substitutions.
|
||||
/// doesn't provide type parameter args.
|
||||
///
|
||||
/// [`expr_ty`]: TypeckResults::expr_ty
|
||||
pub fn pat_ty(&self, pat: &hir::Pat<'_>) -> Ty<'tcx> {
|
||||
|
@ -341,9 +341,9 @@ impl<'tcx> TypeckResults<'tcx> {
|
|||
/// NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in
|
||||
/// some cases, we insert `Adjustment` annotations such as auto-deref or
|
||||
/// auto-ref. The type returned by this function does not consider such
|
||||
/// adjustments. See `expr_ty_adjusted()` instead.
|
||||
/// adjustments. See [`Self::expr_ty_adjusted`] instead.
|
||||
///
|
||||
/// NB (2): This type doesn't provide type parameter substitutions; e.g., if you
|
||||
/// NB (2): This type doesn't provide type parameter args; e.g., if you
|
||||
/// ask for the type of `id` in `id(3)`, it will return `fn(&isize) -> isize`
|
||||
/// instead of `fn(ty) -> T with T = isize`.
|
||||
pub fn expr_ty(&self, expr: &hir::Expr<'_>) -> Ty<'tcx> {
|
||||
|
@ -608,7 +608,7 @@ pub enum UserType<'tcx> {
|
|||
Ty(Ty<'tcx>),
|
||||
|
||||
/// The canonical type is the result of `type_of(def_id)` with the
|
||||
/// given substitutions applied.
|
||||
/// given generic parameters applied.
|
||||
TypeOf(DefId, UserArgs<'tcx>),
|
||||
}
|
||||
|
||||
|
@ -617,7 +617,7 @@ pub trait IsIdentity {
|
|||
}
|
||||
|
||||
impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
||||
/// Returns `true` if this represents a substitution of the form `[?0, ?1, ?2]`,
|
||||
/// Returns `true` if this represents the generic parameters of the form `[?0, ?1, ?2]`,
|
||||
/// i.e., each thing is mapped to a canonical variable with the same index.
|
||||
fn is_identity(&self) -> bool {
|
||||
match self.value {
|
||||
|
@ -631,7 +631,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
|||
match kind.unpack() {
|
||||
GenericArgKind::Type(ty) => match ty.kind() {
|
||||
ty::Bound(debruijn, b) => {
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(*debruijn, ty::INNERMOST);
|
||||
cvar == b.var
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
|||
|
||||
GenericArgKind::Lifetime(r) => match *r {
|
||||
ty::ReBound(debruijn, br) => {
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
cvar == br.var
|
||||
}
|
||||
|
@ -649,7 +649,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
|
|||
|
||||
GenericArgKind::Const(ct) => match ct.kind() {
|
||||
ty::ConstKind::Bound(debruijn, b) => {
|
||||
// We only allow a `ty::INNERMOST` index in substitutions.
|
||||
// We only allow a `ty::INNERMOST` index in generic parameters.
|
||||
assert_eq!(debruijn, ty::INNERMOST);
|
||||
cvar == b
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue