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:
Matthias Krüger 2024-02-12 23:18:54 +01:00 committed by GitHub
commit cb0d74be28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
130 changed files with 576 additions and 543 deletions

View File

@ -691,7 +691,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably)
// borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`.
// These types seem reasonably opaque enough that they could be substituted with their
// These types seem reasonably opaque enough that they could be instantiated with their
// borrowed variants in a function body when we see a move error.
let borrow_level = match *ty.kind() {
ty::Param(_) => tcx

View File

@ -45,7 +45,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
/// be allowed:
/// `fn f<'a: 'b, 'b: 'a>(x: *mut &'b i32) -> impl Sized + 'a { x }`
///
/// Then we map the regions in both the type and the subst to their
/// Then we map the regions in both the type and the generic parameters to their
/// `external_name` giving `concrete_type = &'a i32`,
/// `args = ['static, 'a]`. This will then allow
/// `infer_opaque_definition_from_instantiation` to determine that
@ -77,9 +77,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let args = opaque_type_key.args;
debug!(?concrete_type, ?args);
let mut subst_regions = vec![self.universal_regions.fr_static];
let mut arg_regions = vec![self.universal_regions.fr_static];
let to_universal_region = |vid, subst_regions: &mut Vec<_>| {
let to_universal_region = |vid, arg_regions: &mut Vec<_>| {
trace!(?vid);
let scc = self.constraint_sccs.scc(vid);
trace!(?scc);
@ -88,11 +88,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
}) {
Some(region) => {
let vid = self.universal_regions.to_region_vid(region);
subst_regions.push(vid);
arg_regions.push(vid);
region
}
None => {
subst_regions.push(vid);
arg_regions.push(vid);
ty::Region::new_error_with_message(
infcx.tcx,
concrete_type.span,
@ -106,10 +106,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// This will ensure they get precedence when folding the regions in the concrete type.
if let Some(&ci) = member_constraints.get(&opaque_type_key) {
for &vid in self.member_constraints.choice_regions(ci) {
to_universal_region(vid, &mut subst_regions);
to_universal_region(vid, &mut arg_regions);
}
}
debug!(?subst_regions);
debug!(?arg_regions);
// Next, insert universal regions from args, so we can translate regions that appear
// in them but are not subject to member constraints, for instance closure args.
@ -119,18 +119,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
return region;
}
let vid = self.to_region_vid(region);
to_universal_region(vid, &mut subst_regions)
to_universal_region(vid, &mut arg_regions)
});
debug!(?universal_args);
debug!(?subst_regions);
debug!(?arg_regions);
// Deduplicate the set of regions while keeping the chosen order.
let subst_regions = subst_regions.into_iter().collect::<FxIndexSet<_>>();
debug!(?subst_regions);
let arg_regions = arg_regions.into_iter().collect::<FxIndexSet<_>>();
debug!(?arg_regions);
let universal_concrete_type =
infcx.tcx.fold_regions(concrete_type, |region, _| match *region {
ty::ReVar(vid) => subst_regions
ty::ReVar(vid) => arg_regions
.iter()
.find(|ur_vid| self.eval_equal(vid, **ur_vid))
.and_then(|ur_vid| self.definitions[*ur_vid].external_name)

View File

@ -554,18 +554,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
/// Call this on things you got out of the MIR (so it is as generic as the current
/// stack frame), to bring it into the proper environment for this interpreter.
pub(super) fn subst_from_current_frame_and_normalize_erasing_regions<
pub(super) fn instantiate_from_current_frame_and_normalize_erasing_regions<
T: TypeFoldable<TyCtxt<'tcx>>,
>(
&self,
value: T,
) -> Result<T, ErrorHandled> {
self.subst_from_frame_and_normalize_erasing_regions(self.frame(), value)
self.instantiate_from_frame_and_normalize_erasing_regions(self.frame(), value)
}
/// Call this on things you got out of the MIR (so it is as generic as the provided
/// stack frame), to bring it into the proper environment for this interpreter.
pub(super) fn subst_from_frame_and_normalize_erasing_regions<T: TypeFoldable<TyCtxt<'tcx>>>(
pub(super) fn instantiate_from_frame_and_normalize_erasing_regions<
T: TypeFoldable<TyCtxt<'tcx>>,
>(
&self,
frame: &Frame<'mir, 'tcx, M::Provenance, M::FrameExtra>,
value: T,
@ -656,7 +658,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let layout = from_known_layout(self.tcx, self.param_env, layout, || {
let local_ty = frame.body.local_decls[local].ty;
let local_ty = self.subst_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
let local_ty =
self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
self.layout_of(local_ty)
})?;
@ -791,8 +794,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Make sure all the constants required by this frame evaluate successfully (post-monomorphization check).
if M::POST_MONO_CHECKS {
for &const_ in &body.required_consts {
let c =
self.subst_from_current_frame_and_normalize_erasing_regions(const_.const_)?;
let c = self
.instantiate_from_current_frame_and_normalize_erasing_regions(const_.const_)?;
c.eval(*self.tcx, self.param_env, Some(const_.span)).map_err(|err| {
err.emit_note(*self.tcx);
err

View File

@ -696,9 +696,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
trace!("eval_place_to_op: got {:?}", op);
// Sanity-check the type we ended up with.
if cfg!(debug_assertions) {
let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions(
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
)?;
let normalized_place_ty = self
.instantiate_from_current_frame_and_normalize_erasing_regions(
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
)?;
if !mir_assign_valid_types(
*self.tcx,
self.param_env,
@ -731,8 +732,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
&Copy(place) | &Move(place) => self.eval_place_to_op(place, layout)?,
Constant(constant) => {
let c =
self.subst_from_current_frame_and_normalize_erasing_regions(constant.const_)?;
let c = self.instantiate_from_current_frame_and_normalize_erasing_regions(
constant.const_,
)?;
// This can still fail:
// * During ConstProp, with `TooGeneric` or since the `required_consts` were not all

View File

@ -542,9 +542,10 @@ where
trace!("{:?}", self.dump_place(&place));
// Sanity-check the type we ended up with.
if cfg!(debug_assertions) {
let normalized_place_ty = self.subst_from_current_frame_and_normalize_erasing_regions(
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
)?;
let normalized_place_ty = self
.instantiate_from_current_frame_and_normalize_erasing_regions(
mir_place.ty(&self.frame().body.local_decls, *self.tcx).ty,
)?;
if !mir_assign_valid_types(
*self.tcx,
self.param_env,

View File

@ -235,7 +235,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
}
NullaryOp(ref null_op, ty) => {
let ty = self.subst_from_current_frame_and_normalize_erasing_regions(ty)?;
let ty = self.instantiate_from_current_frame_and_normalize_erasing_regions(ty)?;
let layout = self.layout_of(ty)?;
if let mir::NullOp::SizeOf | mir::NullOp::AlignOf = null_op
&& layout.is_unsized()
@ -276,7 +276,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Cast(cast_kind, ref operand, cast_ty) => {
let src = self.eval_operand(operand, None)?;
let cast_ty =
self.subst_from_current_frame_and_normalize_erasing_regions(cast_ty)?;
self.instantiate_from_current_frame_and_normalize_erasing_regions(cast_ty)?;
self.cast(&src, cast_kind, cast_ty, &dest)?;
}

View File

@ -173,7 +173,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
Drop { place, target, unwind, replace: _ } => {
let frame = self.frame();
let ty = place.ty(&frame.body.local_decls, *self.tcx).ty;
let ty = self.subst_from_frame_and_normalize_erasing_regions(frame, ty)?;
let ty = self.instantiate_from_frame_and_normalize_erasing_regions(frame, ty)?;
let instance = Instance::resolve_drop_in_place(*self.tcx, ty);
if let ty::InstanceDef::DropGlue(_, None) = instance.def {
// This is the branch we enter if and only if the dropped type has no drop glue
@ -672,8 +672,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// Construct the destination place for this argument. At this point all
// locals are still dead, so we cannot construct a `PlaceTy`.
let dest = mir::Place::from(local);
// `layout_of_local` does more than just the substitution we need to get the
// type, but the result gets cached so this avoids calling the substitution
// `layout_of_local` does more than just the instantiation we need to get the
// type, but the result gets cached so this avoids calling the instantiation
// query *again* the next time this local is accessed.
let ty = self.layout_of_local(self.frame(), local, None)?.ty;
if Some(local) == body.spread_arg {

View File

@ -19,11 +19,11 @@ where
}
struct FoundParam;
struct UsedParamsNeedSubstVisitor<'tcx> {
struct UsedParamsNeedInstantiationVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedSubstVisitor<'tcx> {
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for UsedParamsNeedInstantiationVisitor<'tcx> {
type BreakTy = FoundParam;
fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
@ -39,17 +39,17 @@ where
| ty::FnDef(def_id, args) => {
let instance = ty::InstanceDef::Item(def_id);
let unused_params = self.tcx.unused_generic_params(instance);
for (index, subst) in args.into_iter().enumerate() {
for (index, arg) in args.into_iter().enumerate() {
let index = index
.try_into()
.expect("more generic parameters than can fit into a `u32`");
// Only recurse when generic parameters in fns, closures and coroutines
// are used and have to be instantiated.
//
// Just in case there are closures or coroutines within this subst,
// Just in case there are closures or coroutines within this arg,
// recurse.
if unused_params.is_used(index) && subst.has_param() {
return subst.visit_with(self);
if unused_params.is_used(index) && arg.has_param() {
return arg.visit_with(self);
}
}
ControlFlow::Continue(())
@ -66,7 +66,7 @@ where
}
}
let mut vis = UsedParamsNeedSubstVisitor { tcx };
let mut vis = UsedParamsNeedInstantiationVisitor { tcx };
if matches!(ty.visit_with(&mut vis), ControlFlow::Break(FoundParam)) {
throw_inval!(TooGeneric);
} else {

View File

@ -22,9 +22,9 @@ fn foo<T>(x: Vec<T>) {
In this specific case there's a good chance that the transmute is harmless (but
this is not guaranteed by Rust). However, when alignment and enum optimizations
come into the picture, it's quite likely that the sizes may or may not match
with different type parameter substitutions. It's not possible to check this for
_all_ possible types, so `transmute()` simply only accepts types without any
unsubstituted type parameters.
with different type parameter instantiations. It's not possible to check this
for _all_ possible types, so `transmute()` simply only accepts types without any
uninstantiated type parameters.
If you need this, there's a good chance you're doing something wrong. Keep in
mind that Rust doesn't guarantee much about the layout of different structs
@ -32,7 +32,7 @@ mind that Rust doesn't guarantee much about the layout of different structs
there is a solution that avoids the transmute entirely, try it instead.
If it's possible, hand-monomorphize the code by writing the function for each
possible type substitution. It's possible to use traits to do this cleanly,
possible type instantiation. It's possible to use traits to do this cleanly,
for example:
```

View File

@ -15,9 +15,9 @@ There will be an error about `bool` not implementing `Index<u8>`, followed by a
note saying "the type `bool` cannot be indexed by `u8`".
As you can see, you can specify type parameters in curly braces for
substitution with the actual types (using the regular format string syntax) in
a given situation. Furthermore, `{Self}` will substitute to the type (in this
case, `bool`) that we tried to use.
instantiation with the actual types (using the regular format string syntax) in
a given situation. Furthermore, `{Self}` will be instantiated to the type (in
this case, `bool`) that we tried to use.
This error appears when the curly braces contain an identifier which doesn't
match with any of the type parameters or the string `Self`. This might happen

View File

@ -15,9 +15,9 @@ there will be an error about `bool` not implementing `Index<u8>`, followed by a
note saying "the type `bool` cannot be indexed by `u8`".
As you can see, you can specify type parameters in curly braces for
substitution with the actual types (using the regular format string syntax) in
a given situation. Furthermore, `{Self}` will substitute to the type (in this
case, `bool`) that we tried to use.
instantiation with the actual types (using the regular format string syntax) in
a given situation. Furthermore, `{Self}` will be instantiated to the type (in
this case, `bool`) that we tried to use.
This error appears when the curly braces do not contain an identifier. Please
add one of the same name as a type parameter. If you intended to use literal

View File

@ -12,12 +12,12 @@ fn together_we_will_rule_the_galaxy(son: &A) {}
```
A trait object is defined over a single, fully-defined trait. With a regular
default parameter, this parameter can just be substituted in. However, if the
default parameter, this parameter can just be instantiated in. However, if the
default parameter is `Self`, the trait changes for each concrete type; i.e.
`i32` will be expected to implement `A<i32>`, `bool` will be expected to
implement `A<bool>`, etc... These types will not share an implementation of a
fully-defined trait; instead they share implementations of a trait with
different parameters substituted in for each implementation. This is
different parameters instantiated in for each implementation. This is
irreconcilable with what we need to make a trait object work, and is thus
disallowed. Making the trait concrete by explicitly specifying the value of the
defaulted parameter will fix this issue. Fixed example:

View File

@ -14,7 +14,7 @@ let _ = foo::<'static>;
The type of a concrete instance of a generic function is universally quantified
over late-bound lifetime parameters. This is because we want the function to
work for any lifetime substituted for the late-bound lifetime parameter, no
work for any lifetime instantiated for the late-bound lifetime parameter, no
matter where the function is called. Consequently, it doesn't make sense to
specify arguments for late-bound lifetime parameters, since they are not
resolved until the function's call site(s).
@ -56,7 +56,7 @@ let bar_fn3 = bar::<Bar>; // OK
In the definition of `bar`, the lifetime parameter `'a` is late-bound, while
`'b` is early-bound. This is reflected in the type annotation for `bar_fn`,
where `'a` is universally quantified and `'b` is substituted by a specific
where `'a` is universally quantified and `'b` is instantiated with a specific
lifetime. It is not allowed to explicitly specify early-bound lifetime
arguments when late-bound lifetime parameters are present (as for `bar_fn2`,
see [issue #42868](https://github.com/rust-lang/rust/issues/42868)), although

View File

@ -2536,7 +2536,7 @@ pub struct OpaqueTy<'hir> {
/// lifetimes that are captured from the function signature they originate from.
///
/// This is done by generating a new early-bound lifetime parameter local to the
/// opaque which is substituted in the function signature with the late-bound
/// opaque which is instantiated in the function signature with the late-bound
/// lifetime.
///
/// This mapping associated a captured lifetime (first parameter) with the new

View File

@ -153,6 +153,8 @@ hir_analysis_function_not_have_default_implementation = function doesn't have a
hir_analysis_functions_names_duplicated = functions names are duplicated
.note = all `#[rustc_must_implement_one_of]` arguments must be unique
hir_analysis_generic_args_on_overridden_impl = could not resolve generic parameters on overridden impl
hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
.label = cannot specialize default item `{$ident}`
.ok_label = parent `impl` is here
@ -387,8 +389,6 @@ hir_analysis_static_mut_ref_lint = {$shared}reference of mutable static is disco
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
hir_analysis_substs_on_overridden_impl = could not resolve substs on overridden impl
hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
.note = this item must mention the opaque type in its signature in order to be able to register hidden types

View File

@ -336,12 +336,12 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
let projection_ty = if let ty::AssocKind::Fn = assoc_kind {
let mut emitted_bad_param_err = None;
// If we have an method return type bound, then we need to substitute
// If we have an method return type bound, then we need to instantiate
// the method's early bound params with suitable late-bound params.
let mut num_bound_vars = candidate.bound_vars().len();
let args =
candidate.skip_binder().args.extend_to(tcx, assoc_item.def_id, |param, _| {
let subst = match param.kind {
let arg = match param.kind {
ty::GenericParamDefKind::Lifetime => ty::Region::new_bound(
tcx,
ty::INNERMOST,
@ -379,7 +379,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
}
};
num_bound_vars += 1;
subst
arg
});
// Next, we need to check that the return-type notation is being used on
@ -402,12 +402,13 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
// Finally, move the fn return type's bound vars over to account for the early bound
// params (and trait ref's late bound params). This logic is very similar to
// `Predicate::subst_supertrait`, and it's no coincidence why.
// `rustc_middle::ty::predicate::Clause::instantiate_supertrait`
// and it's no coincidence why.
let shifted_output = tcx.shift_bound_var_indices(num_bound_vars, output);
let subst_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args);
let instantiation_output = ty::EarlyBinder::bind(shifted_output).instantiate(tcx, args);
let bound_vars = tcx.late_bound_vars(binding.hir_id);
ty::Binder::bind_with_vars(subst_output, bound_vars)
ty::Binder::bind_with_vars(instantiation_output, bound_vars)
} else {
// Append the generic arguments of the associated type to the `trait_ref`.
candidate.map_bound(|trait_ref| {

View File

@ -1,6 +1,6 @@
use super::IsMethodCall;
use crate::astconv::{
errors::prohibit_assoc_ty_binding, CreateSubstsForGenericArgsCtxt, ExplicitLateBound,
errors::prohibit_assoc_ty_binding, CreateInstantiationsForGenericArgsCtxt, ExplicitLateBound,
GenericArgCountMismatch, GenericArgCountResult, GenericArgPosition,
};
use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
@ -177,9 +177,9 @@ pub fn create_args_for_parent_generic_args<'tcx: 'a, 'a>(
has_self: bool,
self_ty: Option<Ty<'tcx>>,
arg_count: &GenericArgCountResult,
ctx: &mut impl CreateSubstsForGenericArgsCtxt<'a, 'tcx>,
ctx: &mut impl CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>,
) -> GenericArgsRef<'tcx> {
// Collect the segments of the path; we need to substitute arguments
// Collect the segments of the path; we need to instantiate arguments
// for parameters throughout the entire path (wherever there are
// generic parameters).
let mut parent_defs = tcx.generics_of(def_id);
@ -191,7 +191,7 @@ pub fn create_args_for_parent_generic_args<'tcx: 'a, 'a>(
}
// We manually build up the generic arguments, rather than using convenience
// methods in `subst.rs`, so that we can iterate over the arguments and
// methods in `rustc_middle/src/ty/generic_args.rs`, so that we can iterate over the arguments and
// parameters in lock-step linearly, instead of trying to match each pair.
let mut args: SmallVec<[ty::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count);
// Iterate over each segment of the path.

View File

@ -214,7 +214,7 @@ pub struct GenericArgCountResult {
pub correct: Result<(), GenericArgCountMismatch>,
}
pub trait CreateSubstsForGenericArgsCtxt<'a, 'tcx> {
pub trait CreateInstantiationsForGenericArgsCtxt<'a, 'tcx> {
fn args_for_def_id(&mut self, def_id: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool);
fn provided_kind(
@ -366,8 +366,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if generics.has_self {
if generics.parent.is_some() {
// The parent is a trait so it should have at least one subst
// for the `Self` type.
// The parent is a trait so it should have at least one
// generic parameter for the `Self` type.
assert!(!parent_args.is_empty())
} else {
// This item (presumably a trait) needs a self-type.
@ -402,7 +402,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
return (tcx.mk_args(parent_args), arg_count);
}
struct SubstsForAstPathCtxt<'a, 'tcx> {
struct InstantiationsForAstPathCtxt<'a, 'tcx> {
astconv: &'a (dyn AstConv<'tcx> + 'a),
def_id: DefId,
generic_args: &'a GenericArgs<'tcx>,
@ -411,7 +411,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
infer_args: bool,
}
impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for SubstsForAstPathCtxt<'a, 'tcx> {
impl<'a, 'tcx> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>
for InstantiationsForAstPathCtxt<'a, 'tcx>
{
fn args_for_def_id(&mut self, did: DefId) -> (Option<&'a GenericArgs<'tcx>>, bool) {
if did == self.def_id {
(Some(self.generic_args), self.infer_args)
@ -556,7 +558,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
}
let mut args_ctx = SubstsForAstPathCtxt {
let mut args_ctx = InstantiationsForAstPathCtxt {
astconv: self,
def_id,
span,
@ -2412,8 +2414,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let self_ty = self.tcx().type_of(parent).instantiate_identity();
let generic_self_ty = ty::GenericArg::from(self_ty);
let substs = self.tcx().mk_args_from_iter(std::iter::once(generic_self_ty));
sig.instantiate(self.tcx(), substs)
let args = self.tcx().mk_args_from_iter(std::iter::once(generic_self_ty));
sig.instantiate(self.tcx(), args)
} else {
sig.instantiate_identity()
};

View File

@ -175,7 +175,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
ty::PredicateKind::Clause(ty::ClauseKind::Projection(pred)) => {
let pred = bound_predicate.rebind(pred);
// A `Self` within the original bound will be substituted with a
// A `Self` within the original bound will be instantiated with a
// `trait_object_dummy_self`, so check for that.
let references_self = match pred.skip_binder().term.unpack() {
ty::TermKind::Ty(ty) => ty.walk().any(|arg| arg == dummy_self.into()),

View File

@ -1083,7 +1083,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
match t.kind() {
ty::Tuple(list) => list.iter().try_for_each(|t| check_non_exhaustive(tcx, t)),
ty::Array(ty, _) => check_non_exhaustive(tcx, *ty),
ty::Adt(def, subst) => {
ty::Adt(def, args) => {
if !def.did().is_local() {
let non_exhaustive = def.is_variant_list_non_exhaustive()
|| def
@ -1095,13 +1095,13 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
return ControlFlow::Break((
def.descr(),
def.did(),
subst,
args,
non_exhaustive,
));
}
}
def.all_fields()
.map(|field| field.ty(tcx, subst))
.map(|field| field.ty(tcx, args))
.try_for_each(|t| check_non_exhaustive(tcx, t))
}
_ => ControlFlow::Continue(()),

View File

@ -125,9 +125,9 @@ fn check_method_is_structurally_compatible<'tcx>(
/// <'b> fn(t: &'i0 U0, m: &'b N0) -> Foo
/// ```
///
/// We now want to extract and substitute the type of the *trait*
/// We now want to extract and instantiate the type of the *trait*
/// method and compare it. To do so, we must create a compound
/// substitution by combining `trait_to_impl_args` and
/// instantiation by combining `trait_to_impl_args` and
/// `impl_to_placeholder_args`, and also adding a mapping for the method
/// type parameters. We extend the mapping to also include
/// the method parameters.
@ -146,11 +146,11 @@ fn check_method_is_structurally_compatible<'tcx>(
/// vs `'b`). However, the normal subtyping rules on fn types handle
/// this kind of equivalency just fine.
///
/// We now use these substitutions to ensure that all declared bounds are
/// satisfied by the implementation's method.
/// We now use these generic parameters to ensure that all declared bounds
/// are satisfied by the implementation's method.
///
/// We do this by creating a parameter environment which contains a
/// substitution corresponding to `impl_to_placeholder_args`. We then build
/// generic parameter corresponding to `impl_to_placeholder_args`. We then build
/// `trait_to_placeholder_args` and use it to convert the predicates contained
/// in the `trait_m` generics to the placeholder form.
///
@ -454,7 +454,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
let impl_trait_ref =
tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity();
// First, check a few of the same things as `compare_impl_method`,
// just so we don't ICE during substitution later.
// just so we don't ICE during instantiation later.
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
let trait_to_impl_args = impl_trait_ref.args;
@ -543,7 +543,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
// }
// ```
// .. to compile. However, since we use both the normalized and unnormalized
// inputs and outputs from the substituted trait signature, we will end up
// inputs and outputs from the instantiated trait signature, we will end up
// seeing the hidden type of an RPIT in the signature itself. Naively, this
// means that we will use the hidden type to imply the hidden type's own
// well-formedness.
@ -699,7 +699,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
// NOTE(compiler-errors): RPITITs, like all other RPITs, have early-bound
// region args that are synthesized during AST lowering. These are args
// that are appended to the parent args (trait and trait method). However,
// we're trying to infer the unsubstituted type value of the RPITIT inside
// we're trying to infer the uninstantiated type value of the RPITIT inside
// the *impl*, so we can later use the impl's method args to normalize
// an RPITIT to a concrete type (`confirm_impl_trait_in_trait_candidate`).
//
@ -711,7 +711,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
// guarantee that the indices from the trait args and impl args line up.
// So to fix this, we subtract the number of trait args and add the number of
// impl args to *renumber* these early-bound regions to their corresponding
// indices in the impl's substitutions list.
// indices in the impl's generic parameters list.
//
// Also, we only need to account for a difference in trait and impl args,
// since we previously enforce that the trait method and impl method have the

View File

@ -124,14 +124,14 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
let infcx = tcx.infer_ctxt().build();
let ocx = ObligationCtxt::new(&infcx);
// Take the param-env of the adt and substitute the args that show up in
// Take the param-env of the adt and instantiate the args that show up in
// the implementation's self type. This gives us the assumptions that the
// self ty of the implementation is allowed to know just from it being a
// well-formed adt, since that's all we're allowed to assume while proving
// the Drop implementation is not specialized.
//
// We don't need to normalize this param-env or anything, since we're only
// substituting it with free params, so no additional param-env normalization
// instantiating it with free params, so no additional param-env normalization
// can occur on top of what has been done in the param_env query itself.
let param_env =
ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args);

View File

@ -56,7 +56,7 @@ type variable is an instance of a type parameter. That is,
given a generic function `fn foo<T>(t: T)`, while checking the
function `foo`, the type `ty_param(0)` refers to the type `T`, which
is treated in abstract. However, when `foo()` is called, `T` will be
substituted for a fresh type variable `N`. This variable will
instantiated with a fresh type variable `N`. This variable will
eventually be resolved to some concrete type (which might itself be
a type parameter).

View File

@ -618,7 +618,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
// The bounds we that we would require from `to_check`
let mut bounds = FxHashSet::default();
let (regions, types) = GATSubstCollector::visit(gat_def_id.to_def_id(), to_check);
let (regions, types) = GATArgsCollector::visit(gat_def_id.to_def_id(), to_check);
// If both regions and types are empty, then this GAT isn't in the
// set of types we are checking, and we shouldn't try to do clause analysis
@ -787,34 +787,34 @@ fn test_region_obligations<'tcx>(
/// `<P0 as Trait<P1..Pn>>::GAT<Pn..Pm>` and adds the arguments `P0..Pm` into
/// the two vectors, `regions` and `types` (depending on their kind). For each
/// parameter `Pi` also track the index `i`.
struct GATSubstCollector<'tcx> {
struct GATArgsCollector<'tcx> {
gat: DefId,
// Which region appears and which parameter index its substituted for
// Which region appears and which parameter index its instantiated with
regions: FxHashSet<(ty::Region<'tcx>, usize)>,
// Which params appears and which parameter index its substituted for
// Which params appears and which parameter index its instantiated with
types: FxHashSet<(Ty<'tcx>, usize)>,
}
impl<'tcx> GATSubstCollector<'tcx> {
impl<'tcx> GATArgsCollector<'tcx> {
fn visit<T: TypeFoldable<TyCtxt<'tcx>>>(
gat: DefId,
t: T,
) -> (FxHashSet<(ty::Region<'tcx>, usize)>, FxHashSet<(Ty<'tcx>, usize)>) {
let mut visitor =
GATSubstCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() };
GATArgsCollector { gat, regions: FxHashSet::default(), types: FxHashSet::default() };
t.visit_with(&mut visitor);
(visitor.regions, visitor.types)
}
}
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATSubstCollector<'tcx> {
impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for GATArgsCollector<'tcx> {
type BreakTy = !;
fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
match t.kind() {
ty::Alias(ty::Projection, p) if p.def_id == self.gat => {
for (idx, subst) in p.args.iter().enumerate() {
match subst.unpack() {
for (idx, arg) in p.args.iter().enumerate() {
match arg.unpack() {
GenericArgKind::Lifetime(lt) if !lt.is_bound() => {
self.regions.insert((lt, idx));
}
@ -1407,14 +1407,14 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
}
}
// Check that trait predicates are WF when params are substituted by their defaults.
// Check that trait predicates are WF when params are instantiated with their defaults.
// We don't want to overly constrain the predicates that may be written but we want to
// catch cases where a default my never be applied such as `struct Foo<T: Copy = String>`.
// Therefore we check if a predicate which contains a single type param
// with a concrete default is WF with that default substituted.
// with a concrete default is WF with that default instantiated.
// For more examples see tests `defaults-well-formedness.rs` and `type-check-defaults.rs`.
//
// First we build the defaulted substitution.
// First we build the defaulted generic parameters.
let args = GenericArgs::for_item(tcx, def_id.to_def_id(), |param, _| {
match param.kind {
GenericParamDefKind::Lifetime => {
@ -1428,7 +1428,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
let default_ty = tcx.type_of(param.def_id).instantiate_identity();
// ... and it's not a dependent default, ...
if !default_ty.has_param() {
// ... then substitute it with the default.
// ... then instantiate it with the default.
return default_ty.into();
}
}
@ -1441,7 +1441,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
let default_ct = tcx.const_param_default(param.def_id).instantiate_identity();
// ... and it's not a dependent default, ...
if !default_ct.has_param() {
// ... then substitute it with the default.
// ... then instantiate it with the default.
return default_ct.into();
}
}
@ -1451,7 +1451,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
}
});
// Now we build the substituted predicates.
// Now we build the instantiated predicates.
let default_obligations = predicates
.predicates
.iter()
@ -1483,23 +1483,25 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
}
let mut param_count = CountParams::default();
let has_region = pred.visit_with(&mut param_count).is_break();
let substituted_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args);
let instantiated_pred = ty::EarlyBinder::bind(pred).instantiate(tcx, args);
// Don't check non-defaulted params, dependent defaults (including lifetimes)
// or preds with multiple params.
if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region
if instantiated_pred.has_non_region_param()
|| param_count.params.len() > 1
|| has_region
{
None
} else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) {
} else if predicates.predicates.iter().any(|&(p, _)| p == instantiated_pred) {
// Avoid duplication of predicates that contain no parameters, for example.
None
} else {
Some((substituted_pred, sp))
Some((instantiated_pred, sp))
}
})
.map(|(pred, sp)| {
// Convert each of those into an obligation. So if you have
// something like `struct Foo<T: Copy = String>`, we would
// take that predicate `T: Copy`, substitute to `String: Copy`
// take that predicate `T: Copy`, instantiated with `String: Copy`
// (actually that happens in the previous `flat_map` call),
// and then try to prove it (in this case, we'll fail).
//

View File

@ -396,7 +396,7 @@ pub fn coerce_unsized_info<'tcx>(
//
// To check if this impl is legal, we would walk down
// the fields of `Foo` and consider their types with
// both substitutes. We are looking to find that
// both generic parameters. We are looking to find that
// exactly one (non-phantom) field has changed its
// type, which we will expect to be the pointer that
// is becoming fat (we could probably generalize this

View File

@ -71,7 +71,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
// end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, args: [N#0])`.
//
// This causes ICEs (#86580) when building the args for Foo in `fn foo() -> Foo { .. }` as
// we substitute the defaults with the partially built args when we build the args. Subst'ing
// we instantiate the defaults with the partially built args when we build the args. Instantiating
// the `N#0` on the unevaluated const indexes into the empty args we're in the process of building.
//
// We fix this by having this function return the parent's generics ourselves and truncating the

View File

@ -1786,7 +1786,8 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
let bound_predicate = pred.kind();
match bound_predicate.skip_binder() {
ty::ClauseKind::Trait(data) => {
// The order here needs to match what we would get from `subst_supertrait`
// The order here needs to match what we would get from
// `rustc_middle::ty::predicate::Clause::instantiate_supertrait`
let pred_bound_vars = bound_predicate.bound_vars();
let mut all_bound_vars = bound_vars.clone();
all_bound_vars.extend(pred_bound_vars.iter());

View File

@ -119,7 +119,7 @@ pub fn identify_constrained_generic_params<'tcx>(
/// * `<U as Iterator>::Item = T` -- a desugared ProjectionPredicate
///
/// When we, for example, try to go over the trait-reference
/// `IntoIter<u32> as Trait`, we substitute the impl parameters with fresh
/// `IntoIter<u32> as Trait`, we instantiate the impl parameters with fresh
/// variables and match them with the impl trait-ref, so we know that
/// `$U = IntoIter<u32>`.
///

View File

@ -424,8 +424,8 @@ pub struct ManualImplementation {
}
#[derive(Diagnostic)]
#[diag(hir_analysis_substs_on_overridden_impl)]
pub struct SubstsOnOverriddenImpl {
#[diag(hir_analysis_generic_args_on_overridden_impl)]
pub struct GenericArgsOnOverriddenImpl {
#[primary_span]
pub span: Span,
}

View File

@ -34,8 +34,8 @@
//! impl<T, I: Iterator<Item=T>> SpecExtend<T> for I { /* default impl */ }
//! ```
//!
//! We get that the subst for `impl2` are `[T, std::vec::IntoIter<T>]`. `T` is
//! constrained to be `<I as Iterator>::Item`, so we check only
//! We get that the generic pamameters for `impl2` are `[T, std::vec::IntoIter<T>]`.
//! `T` is constrained to be `<I as Iterator>::Item`, so we check only
//! `std::vec::IntoIter<T>` for repeated parameters, which it doesn't have. The
//! predicates of `impl1` are only `T: Sized`, which is also a predicate of
//! `impl2`. So this specialization is sound.
@ -65,7 +65,7 @@
//! cause use after frees with purely safe code in the same way as specializing
//! on traits with methods can.
use crate::errors::SubstsOnOverriddenImpl;
use crate::errors::GenericArgsOnOverriddenImpl;
use crate::{constrained_generic_params as cgp, errors};
use rustc_data_structures::fx::FxHashSet;
@ -179,8 +179,8 @@ fn check_constness(
}
/// Given a specializing impl `impl1`, and the base impl `impl2`, returns two
/// substitutions `(S1, S2)` that equate their trait references. The returned
/// types are expressed in terms of the generics of `impl1`.
/// generic parameters `(S1, S2)` that equate their trait references.
/// The returned types are expressed in terms of the generics of `impl1`.
///
/// Example
///
@ -228,13 +228,13 @@ fn get_impl_args(
let _ = ocx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env);
let Ok(impl2_args) = infcx.fully_resolve(impl2_args) else {
let span = tcx.def_span(impl1_def_id);
let guar = tcx.dcx().emit_err(SubstsOnOverriddenImpl { span });
let guar = tcx.dcx().emit_err(GenericArgsOnOverriddenImpl { span });
return Err(guar);
};
Ok((impl1_args, impl2_args))
}
/// Returns a list of all of the unconstrained subst of the given impl.
/// Returns a list of all of the unconstrained generic parameters of the given impl.
///
/// For example given the impl:
///

View File

@ -229,7 +229,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
/// Here, we should fetch the explicit predicates, which
/// will give us `U: 'static` and `U: Outer`. The latter we
/// can ignore, but we will want to process `U: 'static`,
/// applying the substitution as above.
/// applying the instantiation as above.
fn check_explicit_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
def_id: DefId,
@ -316,7 +316,7 @@ fn check_explicit_predicates<'tcx>(
/// Here, when processing the type of field `outer`, we would request the
/// set of implicit predicates computed for `Inner` thus far. This will
/// initially come back empty, but in next round we will get `U: 'b`.
/// We then apply the substitution `['b => 'a, U => T]` and thus get the
/// We then apply the instantiation `['b => 'a, U => T]` and thus get the
/// requirement that `T: 'a` holds for `Outer`.
fn check_inferred_predicates<'tcx>(
tcx: TyCtxt<'tcx>,
@ -334,7 +334,7 @@ fn check_inferred_predicates<'tcx>(
for (&predicate, &span) in predicates.as_ref().skip_binder() {
// `predicate` is `U: 'b` in the example above.
// So apply the substitution to get `T: 'a`.
// So apply the instantiation to get `T: 'a`.
let ty::OutlivesPredicate(arg, region) =
predicates.rebind(predicate).instantiate(tcx, args);
insert_outlives_predicate(tcx, arg, region, span, required_predicates);

View File

@ -172,16 +172,16 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
trait_ref: ty::TraitRef { def_id: _, args, .. },
polarity: _,
}) => {
for subst in &args[1..] {
subst.visit_with(&mut collector);
for arg in &args[1..] {
arg.visit_with(&mut collector);
}
}
ty::ClauseKind::Projection(ty::ProjectionPredicate {
projection_ty: ty::AliasTy { args, .. },
term,
}) => {
for subst in &args[1..] {
subst.visit_with(&mut collector);
for arg in &args[1..] {
arg.visit_with(&mut collector);
}
term.visit_with(&mut collector);
}

View File

@ -122,7 +122,7 @@ pub(super) fn check_fn<'a, 'tcx>(
if let ty::Dynamic(..) = declared_ret_ty.kind() {
// We have special-cased the case where the function is declared
// `-> dyn Foo` and we don't actually relate it to the
// `fcx.ret_coercion`, so just substitute a type variable.
// `fcx.ret_coercion`, so just instantiate a type variable.
actual_return_ty =
fcx.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::DynReturnFn, span });
debug!("actual_return_ty replaced with {:?}", actual_return_ty);

View File

@ -752,7 +752,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
let mut obligations: Vec<_> = predicates
.iter()
.map(|predicate| {
// For each existential predicate (e.g., `?Self: Clone`) substitute
// For each existential predicate (e.g., `?Self: Clone`) instantiate
// the type of the expression (e.g., `usize` in our example above)
// and then require that the resulting predicate (e.g., `usize: Clone`)
// holds (it does).

View File

@ -1801,7 +1801,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// consistency. But they should be merged as much as possible.
let fru_tys = if self.tcx.features().type_changing_struct_update {
if adt.is_struct() {
// Make some fresh substitutions for our ADT type.
// Make some fresh generic parameters for our ADT type.
let fresh_args = self.fresh_args_for_item(base_expr.span, adt.did());
// We do subtyping on the FRU fields first, so we can
// learn exactly what types we expect the base expr

View File

@ -15,7 +15,7 @@ use rustc_hir_analysis::astconv::generics::{
check_generic_arg_count_for_call, create_args_for_parent_generic_args,
};
use rustc_hir_analysis::astconv::{
AstConv, CreateSubstsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
AstConv, CreateInstantiationsForGenericArgsCtxt, ExplicitLateBound, GenericArgCountMismatch,
GenericArgCountResult, IsMethodCall, PathSeg,
};
use rustc_infer::infer::canonical::{Canonical, OriginalQueryValues, QueryResponse};
@ -187,8 +187,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
/// Given the args that we just converted from the HIR, try to
/// canonicalize them and store them as user-given substitutions
/// (i.e., substitutions that must be respected by the NLL check).
/// canonicalize them and store them as user-given parameters
/// (i.e., parameters that must be respected by the NLL check).
///
/// This should be invoked **before any unifications have
/// occurred**, so that annotations like `Vec<_>` are preserved
@ -741,7 +741,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return Err(TypeError::Mismatch);
}
// Record all the argument types, with the substitutions
// Record all the argument types, with the args
// produced from the above subtyping unification.
Ok(Some(formal_args.iter().map(|&ty| self.resolve_vars_if_possible(ty)).collect()))
})
@ -1171,7 +1171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Now we have to compare the types that the user *actually*
// provided against the types that were *expected*. If the user
// did not provide any types, then we want to substitute inference
// did not provide any types, then we want to instantiate inference
// variables. If the user provided some types, we may still need
// to add defaults. If the user provided *too many* types, that's
// a problem.
@ -1261,14 +1261,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
},
};
struct CreateCtorSubstsContext<'a, 'tcx> {
struct CreateCtorInstantiationsContext<'a, 'tcx> {
fcx: &'a FnCtxt<'a, 'tcx>,
span: Span,
path_segs: &'a [PathSeg],
infer_args_for_err: &'a FxHashSet<usize>,
segments: &'tcx [hir::PathSegment<'tcx>],
}
impl<'tcx, 'a> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for CreateCtorSubstsContext<'a, 'tcx> {
impl<'tcx, 'a> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>
for CreateCtorInstantiationsContext<'a, 'tcx>
{
fn args_for_def_id(
&mut self,
def_id: DefId,
@ -1392,7 +1394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
has_self,
self_ty.map(|s| s.raw),
&arg_count,
&mut CreateCtorSubstsContext {
&mut CreateCtorInstantiationsContext {
fcx: self,
span,
path_segs: &path_segs,
@ -1410,18 +1412,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.add_required_obligations_for_hir(span, def_id, args, hir_id);
// Substitute the values for the type parameters into the type of
// Instantiate the values for the type parameters into the type of
// the referenced item.
let ty = tcx.type_of(def_id);
assert!(!args.has_escaping_bound_vars());
assert!(!ty.skip_binder().has_escaping_bound_vars());
let ty_substituted = self.normalize(span, ty.instantiate(tcx, args));
let ty_instantiated = self.normalize(span, ty.instantiate(tcx, args));
if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty {
// In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
// is inherent, there is no `Self` parameter; instead, the impl needs
// type parameters, which we can infer by unifying the provided `Self`
// with the substituted impl type.
// with the instantiated impl type.
// This also occurs for an enum variant on a type alias.
let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args));
let self_ty = self.normalize(span, self_ty);
@ -1442,13 +1444,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_substituted);
debug!("instantiate_value_path: type of {:?} is {:?}", hir_id, ty_instantiated);
self.write_args(hir_id, args);
(ty_substituted, res)
(ty_instantiated, res)
}
/// Add all the obligations that are required, substituting and normalized appropriately.
/// Add all the obligations that are required, instantiated and normalized appropriately.
pub(crate) fn add_required_obligations_for_hir(
&self,
span: Span,

View File

@ -21,7 +21,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return false;
};
let Some(unsubstituted_pred) = self
let Some(uninstantiated_pred) = self
.tcx
.predicates_of(def_id)
.instantiate_identity(self.tcx)
@ -34,7 +34,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let generics = self.tcx.generics_of(def_id);
let (predicate_args, predicate_self_type_to_point_at) =
match unsubstituted_pred.kind().skip_binder() {
match uninstantiated_pred.kind().skip_binder() {
ty::ClauseKind::Trait(pred) => {
(pred.trait_ref.args.to_vec(), Some(pred.self_ty().into()))
}
@ -343,10 +343,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&& let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind
&& let generics = self.0.tcx.generics_of(self.1)
&& let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id)
&& let Some(subst) =
&& let Some(arg) =
ty::GenericArgs::identity_for_item(self.0.tcx, self.1).get(index as usize)
{
ControlFlow::Break(*subst)
ControlFlow::Break(*arg)
} else {
ty.super_visit_with(self)
}

View File

@ -2133,17 +2133,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
expr_ty: Ty<'tcx>,
) -> bool {
let tcx = self.tcx;
let (adt, substs, unwrap) = match expected.kind() {
let (adt, args, unwrap) = match expected.kind() {
// In case Option<NonZero*> is wanted, but * is provided, suggest calling new
ty::Adt(adt, substs) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
let nonzero_type = substs.type_at(0); // Unwrap option type.
let ty::Adt(adt, substs) = nonzero_type.kind() else {
ty::Adt(adt, args) if tcx.is_diagnostic_item(sym::Option, adt.did()) => {
let nonzero_type = args.type_at(0); // Unwrap option type.
let ty::Adt(adt, args) = nonzero_type.kind() else {
return false;
};
(adt, substs, "")
(adt, args, "")
}
// In case `NonZero<*>` is wanted but `*` is provided, also add `.unwrap()` to satisfy types.
ty::Adt(adt, substs) => (adt, substs, ".unwrap()"),
ty::Adt(adt, args) => (adt, args, ".unwrap()"),
_ => return false,
};
@ -2165,7 +2165,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
("NonZeroI128", tcx.types.i128),
];
let int_type = substs.type_at(0);
let int_type = args.type_at(0);
let Some(nonzero_alias) = coercable_types.iter().find_map(|(nonzero_alias, t)| {
if *t == int_type && self.can_coerce(expr_ty, *t) { Some(nonzero_alias) } else { None }

View File

@ -7,7 +7,7 @@ use rustc_hir::GenericArg;
use rustc_hir_analysis::astconv::generics::{
check_generic_arg_count_for_call, create_args_for_parent_generic_args,
};
use rustc_hir_analysis::astconv::{AstConv, CreateSubstsForGenericArgsCtxt, IsMethodCall};
use rustc_hir_analysis::astconv::{AstConv, CreateInstantiationsForGenericArgsCtxt, IsMethodCall};
use rustc_infer::infer::{self, DefineOpaqueTypes, InferOk};
use rustc_middle::traits::{ObligationCauseCode, UnifyReceiverContext};
use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
@ -95,7 +95,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
// Adjust the self expression the user provided and obtain the adjusted type.
let self_ty = self.adjust_self_ty(unadjusted_self_ty, pick);
// Create substitutions for the method's type parameters.
// Create generic args for the method's type parameters.
let rcvr_args = self.fresh_receiver_args(self_ty, pick);
let all_args = self.instantiate_method_args(pick, segment, rcvr_args);
@ -246,11 +246,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
target
}
/// Returns a set of substitutions for the method *receiver* where all type and region
/// parameters are instantiated with fresh variables. This substitution does not include any
/// Returns a set of generic parameters for the method *receiver* where all type and region
/// parameters are instantiated with fresh variables. This generic paramters does not include any
/// parameters declared on the method itself.
///
/// Note that this substitution may include late-bound regions from the impl level. If so,
/// Note that this generic parameters may include late-bound regions from the impl level. If so,
/// these are instantiated later in the `instantiate_method_sig` routine.
fn fresh_receiver_args(
&mut self,
@ -272,8 +272,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
self.extract_existential_trait_ref(self_ty, |this, object_ty, principal| {
// The object data has no entry for the Self
// Type. For the purposes of this method call, we
// substitute the object type itself. This
// wouldn't be a sound substitution in all cases,
// instantiate the object type itself. This
// wouldn't be a sound instantiation in all cases,
// since each instance of the object type is a
// different existential and hence could match
// distinct types (e.g., if `Self` appeared as an
@ -362,16 +362,18 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
IsMethodCall::Yes,
);
// Create subst for early-bound lifetime parameters, combining
// parameters from the type and those from the method.
// Create generic paramters for early-bound lifetime parameters,
// combining parameters from the type and those from the method.
assert_eq!(generics.parent_count, parent_args.len());
struct MethodSubstsCtxt<'a, 'tcx> {
struct MethodInstantiationsCtxt<'a, 'tcx> {
cfcx: &'a ConfirmContext<'a, 'tcx>,
pick: &'a probe::Pick<'tcx>,
seg: &'a hir::PathSegment<'tcx>,
}
impl<'a, 'tcx> CreateSubstsForGenericArgsCtxt<'a, 'tcx> for MethodSubstsCtxt<'a, 'tcx> {
impl<'a, 'tcx> CreateInstantiationsForGenericArgsCtxt<'a, 'tcx>
for MethodInstantiationsCtxt<'a, 'tcx>
{
fn args_for_def_id(
&mut self,
def_id: DefId,
@ -437,7 +439,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
false,
None,
&arg_count_correct,
&mut MethodSubstsCtxt { cfcx: self, pick, seg },
&mut MethodInstantiationsCtxt { cfcx: self, pick, seg },
);
// When the method is confirmed, the `args` includes
@ -538,15 +540,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
debug!("instantiate_method_sig(pick={:?}, all_args={:?})", pick, all_args);
// Instantiate the bounds on the method with the
// type/early-bound-regions substitutions performed. There can
// type/early-bound-regions instatiations performed. There can
// be no late-bound regions appearing here.
let def_id = pick.item.def_id;
let method_predicates = self.tcx.predicates_of(def_id).instantiate(self.tcx, all_args);
debug!("method_predicates after subst = {:?}", method_predicates);
debug!("method_predicates after instantitation = {:?}", method_predicates);
let sig = self.tcx.fn_sig(def_id).instantiate(self.tcx, all_args);
debug!("type scheme substituted, sig={:?}", sig);
debug!("type scheme instantiated, sig={:?}", sig);
let sig = self.instantiate_binder_with_fresh_vars(sig);
debug!("late-bound lifetimes from method instantiated, sig={:?}", sig);

View File

@ -38,7 +38,7 @@ pub struct MethodCallee<'tcx> {
pub args: GenericArgsRef<'tcx>,
/// Instantiated method signature, i.e., it has been
/// substituted, normalized, and has had late-bound
/// instantiated, normalized, and has had late-bound
/// lifetimes replaced with inference variables.
pub sig: ty::FnSig<'tcx>,
}
@ -395,7 +395,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!("lookup_in_trait_adjusted: method_item={:?}", method_item);
let mut obligations = vec![];
// Instantiate late-bound regions and substitute the trait
// Instantiate late-bound regions and instantiate the trait
// parameters into the method type to get the actual method type.
//
// N.B., instantiate late-bound regions before normalizing the

View File

@ -111,7 +111,7 @@ pub(crate) struct Candidate<'tcx> {
// The way this is handled is through `xform_self_ty`. It contains
// the receiver type of this candidate, but `xform_self_ty`,
// `xform_ret_ty` and `kind` (which contains the predicates) have the
// generic parameters of this candidate substituted with the *same set*
// generic parameters of this candidate instantiated with the *same set*
// of inference variables, which acts as some weird sort of "query".
//
// When we check out a candidate, we require `xform_self_ty` to be
@ -799,7 +799,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
// the `Self` type. An [`ObjectSafetyViolation::SupertraitSelf`] error
// will be reported by `object_safety.rs` if the method refers to the
// `Self` type anywhere other than the receiver. Here, we use a
// substitution that replaces `Self` with the object type itself. Hence,
// instantiation that replaces `Self` with the object type itself. Hence,
// a `&self` method will wind up with an argument type like `&dyn Trait`.
let trait_ref = principal.with_self_ty(self.tcx, self_ty);
self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| {
@ -1857,8 +1857,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
assert!(!args.has_escaping_bound_vars());
// It is possible for type parameters or early-bound lifetimes
// to appear in the signature of `self`. The substitutions we
// are given do not include type/lifetime parameters for the
// to appear in the signature of `self`. The generic parameters
// we are given do not include type/lifetime parameters for the
// method yet. So create fresh variables here for those too,
// if there are any.
let generics = self.tcx.generics_of(method);
@ -1889,7 +1889,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
self.instantiate_bound_regions_with_erased(xform_fn_sig)
}
/// Gets the type of an impl and generate substitutions with inference vars.
/// Gets the type of an impl and generate generic parameters with inference vars.
fn impl_ty_and_args(
&self,
impl_def_id: DefId,
@ -1913,7 +1913,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
/// late-bound regions with 'static. Otherwise, if we were going to replace late-bound
/// regions with actual region variables as is proper, we'd have to ensure that the same
/// region got replaced with the same variable, which requires a bit more coordination
/// and/or tracking the substitution and
/// and/or tracking the instantiations and
/// so forth.
fn instantiate_bound_regions_with_erased<T>(&self, value: ty::Binder<'tcx, T>) -> T
where

View File

@ -357,7 +357,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
PlaceOp::Deref => None,
PlaceOp::Index => {
// We would need to recover the `T` used when we resolve `<_ as Index<T>>::index`
// in try_index_step. This is the subst at index 1.
// in try_index_step. This is the arg at index 1.
//
// Note: we should *not* use `expr_ty` of index_expr here because autoderef
// during coercions can cause type of index_expr to differ from `T` (#72002).

View File

@ -1,6 +1,6 @@
// Type resolution: the phase that finds all the types in the AST with
// unresolved type variables and replaces "ty_var" types with their
// substitutions.
// generic parameters.
use crate::FnCtxt;
use rustc_data_structures::unord::ExtendUnord;
@ -621,7 +621,7 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
self.write_ty_to_typeck_results(hir_id, n_ty);
debug!(?n_ty);
// Resolve any substitutions
// Resolve any generic parameters
if let Some(args) = self.fcx.typeck_results.borrow().node_args_opt(hir_id) {
let args = self.resolve(args, &span);
debug!("write_args_to_tcx({:?}, {:?})", hir_id, args);

View File

@ -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,

View File

@ -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,

View File

@ -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)
})
}

View File

@ -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)
}

View File

@ -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`).
///

View File

@ -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:
//

View File

@ -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

View File

@ -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,
)
}

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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> {

View File

@ -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)
}
}

View File

@ -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.
///

View File

@ -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; }

View File

@ -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)
},
);

View File

@ -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.

View File

@ -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(
_,

View File

@ -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>,

View File

@ -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 {

View File

@ -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>,
}

View File

@ -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(..)
@ -669,13 +669,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)

View File

@ -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:
@ -1672,7 +1672,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 {

View File

@ -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)
}
}

View File

@ -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:?}"),

View File

@ -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:

View File

@ -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.

View File

@ -55,19 +55,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>>,
@ -348,7 +348,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> {
@ -360,9 +360,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> {
@ -627,7 +627,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>),
}
@ -636,7 +636,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 {
@ -650,7 +650,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
}
@ -659,7 +659,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
}
@ -668,7 +668,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
}

View File

@ -811,7 +811,7 @@ impl<'tcx> Cx<'tcx> {
let user_provided_type = match res {
// A reference to something callable -- e.g., a fn, method, or
// a tuple-struct or tuple-variant. This has the type of a
// `Fn` but with the user-given substitutions.
// `Fn` but with the user-given generic parameters.
Res::Def(DefKind::Fn, _)
| Res::Def(DefKind::AssocFn, _)
| Res::Def(DefKind::Ctor(_, CtorKind::Fn), _)
@ -822,7 +822,7 @@ impl<'tcx> Cx<'tcx> {
// A unit struct/variant which is used as a value (e.g.,
// `None`). This has the type of the enum/struct that defines
// this variant -- but with the substitutions given by the
// this variant -- but with the generic parameters given by the
// user.
Res::Def(DefKind::Ctor(_, CtorKind::Const), _) => {
self.user_args_applied_to_ty_of_hir_id(hir_id).map(Box::new)

View File

@ -7,7 +7,7 @@ pub(crate) trait UserAnnotatedTyHelpers<'tcx> {
fn typeck_results(&self) -> &ty::TypeckResults<'tcx>;
/// Looks up the type associated with this hir-id and applies the
/// user-given substitutions; the hir-id must map to a suitable
/// user-given generic parameters; the hir-id must map to a suitable
/// type.
fn user_args_applied_to_ty_of_hir_id(
&self,

View File

@ -36,10 +36,10 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
ty::Tuple(tys) => {
depth == 0 || tys.iter().any(|ty| may_contain_reference(ty, depth - 1, tcx))
}
ty::Adt(adt, subst) => {
ty::Adt(adt, args) => {
depth == 0
|| adt.variants().iter().any(|v| {
v.fields.iter().any(|f| may_contain_reference(f.ty(tcx, subst), depth - 1, tcx))
v.fields.iter().any(|f| may_contain_reference(f.ty(tcx, args), depth - 1, tcx))
})
}
// Conservative fallback

View File

@ -205,8 +205,8 @@ pub fn deduced_param_attrs<'tcx>(
|(arg_index, local_decl)| DeducedParamAttrs {
read_only: !deduce_read_only.mutable_args.contains(arg_index)
// We must normalize here to reveal opaques and normalize
// their substs, otherwise we'll see exponential blow-up in
// compile times: #113372
// their generic parameters, otherwise we'll see exponential
// blow-up in compile times: #113372
&& tcx
.normalize_erasing_regions(param_env, local_decl.ty)
.is_freeze(tcx, param_env),

View File

@ -63,7 +63,7 @@ impl<'tcx> Visitor<'tcx> for FunctionItemRefChecker<'_, 'tcx> {
impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
/// Emits a lint for function reference arguments bound by `fmt::Pointer` in calls to the
/// function defined by `def_id` with the substitutions `args_ref`.
/// function defined by `def_id` with the generic parameters `args_ref`.
fn check_bound_args(
&self,
def_id: DefId,
@ -83,11 +83,11 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
for inner_ty in arg_def.walk().filter_map(|arg| arg.as_type()) {
// If the inner type matches the type bound by `Pointer`
if inner_ty == bound_ty {
// Do a substitution using the parameters from the callsite
let subst_ty =
// Do an instantiation using the parameters from the callsite
let instantiated_ty =
EarlyBinder::bind(inner_ty).instantiate(self.tcx, args_ref);
if let Some((fn_id, fn_args)) =
FunctionItemRefChecker::is_fn_ref(subst_ty)
FunctionItemRefChecker::is_fn_ref(instantiated_ty)
{
let mut span = self.nth_arg_span(args, arg_num);
if span.from_expansion() {

View File

@ -853,10 +853,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
fn simplify_discriminant(&mut self, place: VnIndex) -> Option<VnIndex> {
if let Value::Aggregate(enum_ty, variant, _) = *self.get(place)
&& let AggregateTy::Def(enum_did, enum_substs) = enum_ty
&& let AggregateTy::Def(enum_did, enum_args) = enum_ty
&& let DefKind::Enum = self.tcx.def_kind(enum_did)
{
let enum_ty = self.tcx.type_of(enum_did).instantiate(self.tcx, enum_substs);
let enum_ty = self.tcx.type_of(enum_did).instantiate(self.tcx, enum_args);
let discr = self.ecx.discriminant_for_variant(enum_ty, variant).ok()?;
return Some(self.insert_scalar(discr.to_scalar(), discr.layout.ty));
}
@ -899,13 +899,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
assert!(!fields.is_empty());
(AggregateTy::Tuple, FIRST_VARIANT)
}
AggregateKind::Closure(did, substs)
| AggregateKind::CoroutineClosure(did, substs)
| AggregateKind::Coroutine(did, substs) => {
(AggregateTy::Def(did, substs), FIRST_VARIANT)
}
AggregateKind::Adt(did, variant_index, substs, _, None) => {
(AggregateTy::Def(did, substs), variant_index)
AggregateKind::Closure(did, args)
| AggregateKind::CoroutineClosure(did, args)
| AggregateKind::Coroutine(did, args) => (AggregateTy::Def(did, args), FIRST_VARIANT),
AggregateKind::Adt(did, variant_index, args, _, None) => {
(AggregateTy::Def(did, args), variant_index)
}
// Do not track unions.
AggregateKind::Adt(_, _, _, _, Some(_)) => return None,

View File

@ -80,7 +80,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
}
// These have no own callable MIR.
InstanceDef::Intrinsic(_) | InstanceDef::Virtual(..) => continue,
// These have MIR and if that MIR is inlined, substituted and then inlining is run
// These have MIR and if that MIR is inlined, instantiated and then inlining is run
// again, a function item can end up getting inlined. Thus we'll be able to cause
// a cycle that way
InstanceDef::VTableShim(_)
@ -95,7 +95,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
// This shim does not call any other functions, thus there can be no recursion.
InstanceDef::FnPtrAddrShim(..) => continue,
InstanceDef::DropGlue(..) => {
// FIXME: A not fully substituted drop shim can cause ICEs if one attempts to
// FIXME: A not fully instantiated drop shim can cause ICEs if one attempts to
// have its MIR built. Likely oli-obk just screwed up the `ParamEnv`s, so this
// needs some more analysis.
if callee.has_param() {

View File

@ -208,7 +208,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
// Only bother looking more if it's easy to know what we're calling
let Some((fn_def_id, fn_args)) = func.const_fn_def() else { return };
// Clone needs one subst, so we can cheaply rule out other stuff
// Clone needs one arg, so we can cheaply rule out other stuff
if fn_args.len() != 1 {
return;
}

View File

@ -436,7 +436,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
//
// We manually filter the predicates, skipping anything that's not
// "global". We are in a potentially generic context
// (e.g. we are evaluating a function without substituting generic
// (e.g. we are evaluating a function without instantiating generic
// parameters, so this filtering serves two purposes:
//
// 1. We skip evaluating any predicates that we would
@ -576,10 +576,10 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&inline::Inline,
// Code from other crates may have storage markers, so this needs to happen after inlining.
&remove_storage_markers::RemoveStorageMarkers,
// Inlining and substitution may introduce ZST and useless drops.
// Inlining and instantiation may introduce ZST and useless drops.
&remove_zsts::RemoveZsts,
&remove_unneeded_drops::RemoveUnneededDrops,
// Type substitution may create uninhabited enums.
// Type instantiation may create uninhabited enums.
&uninhabited_enum_branching::UninhabitedEnumBranching,
&unreachable_prop::UnreachablePropagation,
&o1(simplify::SimplifyCfg::AfterUninhabitedEnumBranching),
@ -673,7 +673,7 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
}
/// Fetch all the promoteds of an item and prepare their MIR bodies to be ready for
/// constant evaluation once all substitutions become known.
/// constant evaluation once all generic parameters become known.
fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_>> {
if tcx.is_constructor(def.to_def_id()) {
return tcx.arena.alloc(IndexVec::new());

View File

@ -44,7 +44,7 @@ use crate::ssa::{SsaLocals, StorageLiveLocals};
///
/// # Liveness
///
/// When performing a substitution, we must take care not to introduce uses of dangling locals.
/// When performing an instantiation, we must take care not to introduce uses of dangling locals.
/// To ensure this, we walk the body with the `MaybeStorageDead` dataflow analysis:
/// - if we want to replace `*x` by reborrow `*y` and `y` may be dead, we allow replacement and
/// mark storage statements on `y` for removal;
@ -55,7 +55,7 @@ use crate::ssa::{SsaLocals, StorageLiveLocals};
///
/// For `&mut` borrows, we also need to preserve the uniqueness property:
/// we must avoid creating a state where we interleave uses of `*_1` and `_2`.
/// To do it, we only perform full substitution of mutable borrows:
/// To do it, we only perform full instantiation of mutable borrows:
/// we replace either all or none of the occurrences of `*_1`.
///
/// Some care has to be taken when `_1` is copied in other locals.
@ -63,10 +63,10 @@ use crate::ssa::{SsaLocals, StorageLiveLocals};
/// _3 = *_1;
/// _4 = _1
/// _5 = *_4
/// In such cases, fully substituting `_1` means fully substituting all of the copies.
/// In such cases, fully instantiating `_1` means fully instantiating all of the copies.
///
/// For immutable borrows, we do not need to preserve such uniqueness property,
/// so we perform all the possible substitutions without removing the `_1 = &_2` statement.
/// so we perform all the possible instantiations without removing the `_1 = &_2` statement.
pub struct ReferencePropagation;
impl<'tcx> MirPass<'tcx> for ReferencePropagation {

View File

@ -477,7 +477,7 @@ struct CloneShimBuilder<'tcx> {
impl<'tcx> CloneShimBuilder<'tcx> {
fn new(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) -> Self {
// we must subst the self_ty because it's
// we must instantiate the self_ty because it's
// otherwise going to be TySelf and we can't index
// or access fields of a Place of type TySelf.
let sig = tcx.fn_sig(def_id).instantiate(tcx, &[self_ty.into()]);
@ -716,8 +716,8 @@ fn build_call_shim<'tcx>(
call_kind: CallKind<'tcx>,
) -> Body<'tcx> {
// `FnPtrShim` contains the fn pointer type that a call shim is being built for - this is used
// to substitute into the signature of the shim. It is not necessary for users of this
// MIR body to perform further substitutions (see `InstanceDef::has_polymorphic_mir_body`).
// to instantiate into the signature of the shim. It is not necessary for users of this
// MIR body to perform further instantiations (see `InstanceDef::has_polymorphic_mir_body`).
let (sig_args, untuple_args) = if let ty::InstanceDef::FnPtrShim(_, ty) = instance {
let sig = tcx.instantiate_bound_regions_with_erased(ty.fn_sig(tcx));

View File

@ -170,7 +170,7 @@ impl SsaLocals {
/// _c => _a
/// _d => _a // transitively through _c
///
/// Exception: we do not see through the return place, as it cannot be substituted.
/// Exception: we do not see through the return place, as it cannot be instantiated.
pub fn copy_classes(&self) -> &IndexSlice<Local, Local> {
&self.copy_classes
}

View File

@ -62,7 +62,7 @@
//! syntactic items in the source code. We find them by walking the HIR of the
//! crate, and whenever we hit upon a public function, method, or static item,
//! we create a mono item consisting of the items DefId and, since we only
//! consider non-generic items, an empty type-substitution set. (In eager
//! consider non-generic items, an empty type-parameters set. (In eager
//! collection mode, during incremental compilation, all non-generic functions
//! are considered as roots, as well as when the `-Clink-dead-code` option is
//! specified. Functions marked `#[no_mangle]` and functions called by inlinable
@ -1383,11 +1383,11 @@ fn create_mono_items_for_default_impls<'tcx>(
// items, we never actually check that the predicates of this impl are satisfied
// in a empty reveal-all param env (i.e. with no assumptions).
//
// Even though this impl has no type or const substitutions, because we don't
// Even though this impl has no type or const generic parameters, because we don't
// consider higher-ranked predicates such as `for<'a> &'a mut [u8]: Copy` to
// be trivially false. We must now check that the impl has no impossible-to-satisfy
// predicates.
if tcx.subst_and_check_impossible_predicates((item.owner_id.to_def_id(), impl_args)) {
if tcx.instantiate_and_check_impossible_predicates((item.owner_id.to_def_id(), impl_args)) {
return;
}
@ -1404,7 +1404,7 @@ fn create_mono_items_for_default_impls<'tcx>(
}
// As mentioned above, the method is legal to eagerly instantiate if it
// only has lifetime substitutions. This is validated by
// only has lifetime generic parameters. This is validated by
let args = trait_ref.args.extend_to(tcx, method.def_id, only_region_params);
let instance = ty::Instance::expect_resolve(tcx, param_env, method.def_id, args);

View File

@ -90,7 +90,7 @@ fn should_polymorphize<'tcx>(
def_id: DefId,
instance: ty::InstanceDef<'tcx>,
) -> bool {
// If an instance's MIR body is not polymorphic then the modified substitutions that are
// If an instance's MIR body is not polymorphic then the modified generic parameters that are
// derived from polymorphization's result won't make any difference.
if !instance.has_polymorphic_mir_body() {
return false;

View File

@ -263,11 +263,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
for &(variant, field) in indices {
match current_ty.kind() {
ty::Adt(def, subst) => {
ty::Adt(def, args) => {
let field = &def.variant(variant).fields[field];
self.insert_def_id(field.did);
let field_ty = field.ty(self.tcx, subst);
let field_ty = field.ty(self.tcx, args);
current_ty = self.tcx.normalize_erasing_regions(param_env, field_ty);
}

View File

@ -173,7 +173,7 @@ impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
variant.fields.iter().enumerate().filter_map(move |(i, field)| {
let ty = field.ty(cx.tcx, args);
// `field.ty()` doesn't normalize after substituting.
// `field.ty()` doesn't normalize after instantiating.
let ty = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
let is_visible = adt.is_enum() || field.vis.is_accessible_from(cx.module, cx.tcx);
let is_uninhabited = (cx.tcx.features().exhaustive_patterns

View File

@ -133,7 +133,7 @@ where
if V::SHALLOW {
ControlFlow::Continue(())
} else {
assoc_args.iter().try_for_each(|subst| subst.visit_with(self))
assoc_args.iter().try_for_each(|arg| arg.visit_with(self))
}
}
@ -209,7 +209,7 @@ where
// Visitors searching for minimal visibility/reachability want to
// conservatively approximate associated types like `Type::Alias`
// as visible/reachable even if `Type` is private.
// Ideally, associated types should be substituted in the same way as
// Ideally, associated types should be instantiated in the same way as
// free type aliases, but this isn't done yet.
return ControlFlow::Continue(());
}
@ -230,7 +230,7 @@ where
} else if kind == ty::Projection {
self.visit_projection_ty(data)
} else {
data.args.iter().try_for_each(|subst| subst.visit_with(self))
data.args.iter().try_for_each(|arg| arg.visit_with(self))
};
}
ty::Dynamic(predicates, ..) => {

View File

@ -369,7 +369,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
fn instance_ty(&self, def: InstanceDef) -> stable_mir::ty::Ty {
let mut tables = self.0.borrow_mut();
let instance = tables.instances[def];
assert!(!instance.has_non_region_param(), "{instance:?} needs further substitution");
assert!(!instance.has_non_region_param(), "{instance:?} needs further instantiation");
instance.ty(tables.tcx, ParamEnv::reveal_all()).stable(&mut *tables)
}

View File

@ -99,7 +99,7 @@ fn get_symbol_hash<'tcx>(
instance: Instance<'tcx>,
// type of the item, without any generic
// parameters substituted; this is
// parameters instantiated; this is
// included in the hash as a kind of
// safeguard.
item_type: Ty<'tcx>,

View File

@ -251,8 +251,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
None => "M",
});
// Encode impl generic params if the substitutions contain parameters (implying
// polymorphization is enabled) and this isn't an inherent impl.
// Encode impl generic params if the generic parameters contain non-region parameters
// (implying polymorphization is enabled) and this isn't an inherent impl.
if impl_trait_ref.is_some() && args.iter().any(|a| a.has_non_region_param()) {
self.path_generic_args(
|this| {

View File

@ -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()

View File

@ -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)?;

View File

@ -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(

View File

@ -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)),
);

View File

@ -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)?;

View File

@ -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

View File

@ -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,

View File

@ -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);

Some files were not shown because too many files have changed in this diff Show More