subst -> instantiate

This commit is contained in:
lcnr 2023-09-25 15:46:38 +02:00
parent af68593179
commit 3c52a3e280
25 changed files with 66 additions and 75 deletions

View File

@ -1664,7 +1664,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
lifetime.ident,
));
// Now make an arg that we can use for the substs of the opaque tykind.
// Now make an arg that we can use for the generic params of the opaque tykind.
let id = self.next_node_id();
let lifetime_arg = self.new_named_lifetime_with_res(id, lifetime.ident, res);
let duplicated_lifetime_def_id = self.local_def_id(duplicated_lifetime_node_id);

View File

@ -27,7 +27,7 @@ pub(crate) struct RegionName {
/// This helps to print the right kinds of diagnostics.
#[derive(Debug, Clone)]
pub(crate) enum RegionNameSource {
/// A bound (not free) region that was substituted at the def site (not an HRTB).
/// A bound (not free) region that was instantiated at the def site (not an HRTB).
NamedEarlyBoundRegion(Span),
/// A free region that the user has a name (`'a`) for.
NamedFreeRegion(Span),
@ -619,7 +619,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
// programs, so we need to use delay_span_bug here. See #82126.
self.infcx.tcx.sess.delay_span_bug(
hir_arg.span(),
format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"),
format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"),
);
}
}

View File

@ -2250,7 +2250,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
// Query canonicalization can create local superuniverses (for example in
// `InferCtx::query_response_substitution_guess`), but they don't have an associated
// `InferCtx::query_response_instantiation_guess`), but they don't have an associated
// `UniverseInfo` explaining why they were created.
// This can cause ICEs if these causes are accessed in diagnostics, for example in issue
// #114907 where this happens via liveness and dropck outlives results.

View File

@ -1007,7 +1007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
}
pub(super) fn register_predefined_opaques_in_new_solver(&mut self) {
// OK to use the identity substitutions for each opaque type key, since
// OK to use the identity arguments for each opaque type key, since
// we remap opaques from HIR typeck back to their definition params.
let opaques: Vec<_> = self
.infcx

View File

@ -639,10 +639,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
};
let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
let subst_mapping =
iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static }
}
fn compute_inputs_and_output(

View File

@ -100,9 +100,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
stack = &stack[..index + ENCODE_METADATA.len()];
}
const SUBST_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::subst_and_normalize_erasing_regions";
if let Some(index) = stack.find(SUBST_AND_NORMALIZE_ERASING_REGIONS) {
stack = &stack[..index + SUBST_AND_NORMALIZE_ERASING_REGIONS.len()];
const INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::instantiate_and_normalize_erasing_regions";
if let Some(index) = stack.find(INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS) {
stack = &stack[..index + INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS.len()];
}
const NORMALIZE_ERASING_LATE_BOUND_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::normalize_erasing_late_bound_regions";

View File

@ -359,7 +359,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
{
self.instance.subst_mir_and_normalize_erasing_regions(
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(value),

View File

@ -90,7 +90,7 @@ fn make_mir_scope<'ll, 'tcx>(
Some((callee, _)) => {
// FIXME(eddyb) this would be `self.monomorphize(&callee)`
// if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
let callee = cx.tcx.subst_and_normalize_erasing_regions(
let callee = cx.tcx.instantiate_and_normalize_erasing_regions(
instance.args,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(callee),

View File

@ -529,7 +529,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) {
// If the method does *not* belong to a trait, proceed
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions(
instance.args,
ty::ParamEnv::reveal_all(),
cx.tcx.type_of(impl_def_id),

View File

@ -118,7 +118,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
T: Copy + TypeFoldable<TyCtxt<'tcx>>,
{
debug!("monomorphize: self.instance={:?}", self.instance);
self.instance.subst_mir_and_normalize_erasing_regions(
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.cx.tcx(),
ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(value),

View File

@ -569,7 +569,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> Result<T, ErrorHandled> {
frame
.instance
.try_subst_mir_and_normalize_erasing_regions(
.try_instantiate_mir_and_normalize_erasing_regions(
*self.tcx,
self.param_env,
ty::EarlyBinder::bind(value),

View File

@ -4,7 +4,7 @@ use rustc_middle::ty::{
};
use std::ops::ControlFlow;
/// Checks whether a type contains generic parameters which require substitution.
/// Checks whether a type contains generic parameters which must be instantiated.
///
/// In case it does, returns a `TooGeneric` const eval error. Note that due to polymorphization
/// types may be "concrete enough" even though they still contain generic parameters in
@ -43,7 +43,8 @@ where
.try_into()
.expect("more generic parameters than can fit into a `u32`");
// Only recurse when generic parameters in fns, closures and generators
// are used and require substitution.
// are used and have to be instantiated.
//
// Just in case there are closures or generators within this subst,
// recurse.
if unused_params.is_used(index) && subst.has_param() {

View File

@ -558,8 +558,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
}
}
/// A faster version of the validation pass that only checks those things which may break when apply
/// generic substitutions.
/// A faster version of the validation pass that only checks those things which may break when
/// instantiating any generic parameters.
pub fn validate_types<'tcx>(
tcx: TyCtxt<'tcx>,
mir_phase: MirPhase,

View File

@ -162,14 +162,13 @@ fn foo<T>(x: T) {
```
The machine code for `foo::<u8>()`, `foo::<bool>()`, `foo::<String>()`, or any
other type substitution is different. Hence the compiler generates the
other instantiation is different. Hence the compiler generates the
implementation on-demand. If you call `foo()` with a `bool` parameter, the
compiler will only generate code for `foo::<bool>()`. When we have additional
type parameters, the number of monomorphized implementations the compiler
generates does not grow drastically, since the compiler will only generate an
implementation if the function is called with unparameterized substitutions
(i.e., substitutions where none of the substituted types are themselves
parameterized).
implementation if the function is called with fully concrete arguments
(i.e., arguments which do not contain any generic parameters).
However, with trait objects we have to make a table containing _every_ object
that implements the trait. Now, if it has type parameters, we need to add

View File

@ -427,7 +427,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
let bound_vars = tcx.late_bound_vars(binding.hir_id);
ty::Binder::bind_with_vars(subst_output, bound_vars)
} else {
// Include substitutions for generic parameters of associated types
// Append the generic arguments of the associated type to the `trait_ref`.
candidate.map_bound(|trait_ref| {
let ident = Ident::new(assoc_item.name, binding.item_name.span);
let item_segment = hir::PathSegment {

View File

@ -139,22 +139,22 @@ fn generic_arg_mismatch_err(
err.emit()
}
/// Creates the relevant generic argument substitutions
/// Creates the relevant generic arguments
/// corresponding to a set of generic parameters. This is a
/// rather complex function. Let us try to explain the role
/// of each of its parameters:
///
/// To start, we are given the `def_id` of the thing we are
/// creating the substitutions for, and a partial set of
/// substitutions `parent_args`. In general, the substitutions
/// for an item begin with substitutions for all the "parents" of
/// To start, we are given the `def_id` of the thing whose generic
/// parameters we are instantiating, and a partial set of
/// arguments `parent_args`. In general, the generic arguments
/// for an item begin with arguments for all the "parents" of
/// that item -- e.g., for a method it might include the
/// parameters from the impl.
///
/// Therefore, the method begins by walking down these parents,
/// starting with the outermost parent and proceed inwards until
/// it reaches `def_id`. For each parent `P`, it will check `parent_args`
/// first to see if the parent's substitutions are listed in there. If so,
/// first to see if the parent's arguments are listed in there. If so,
/// we can append those and move on. Otherwise, it invokes the
/// three callback functions:
///
@ -188,7 +188,7 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>(
stack.push((def_id, parent_defs));
}
// We manually build up the substitution, rather than using convenience
// We manually build up the generic arguments, rather than using convenience
// methods in `subst.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);
@ -196,7 +196,8 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>(
while let Some((def_id, defs)) = stack.pop() {
let mut params = defs.params.iter().peekable();
// If we have already computed substitutions for parents, we can use those directly.
// If we have already computed the generic arguments for parents,
// we can use those directly.
while let Some(&param) = params.peek() {
if let Some(&kind) = parent_args.get(param.index as usize) {
args.push(kind);

View File

@ -289,7 +289,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
}
/// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
/// returns an appropriate set of substitutions for this particular reference to `I`.
/// returns an appropriate set of generic arguments for this particular reference to `I`.
pub fn ast_path_args_for_ty(
&self,
span: Span,
@ -315,7 +315,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// Given the type/lifetime/const arguments provided to some path (along with
/// an implicit `Self`, if this is a trait reference), returns the complete
/// set of substitutions. This may involve applying defaulted type parameters.
/// set of generic arguments. This may involve applying defaulted type parameters.
/// Constraints on associated types are created from `create_assoc_bindings_for_generic_args`.
///
/// Example:

View File

@ -118,7 +118,7 @@ impl<'tcx> Instance<'tcx> {
/// 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());
tcx.subst_and_normalize_erasing_regions(self.args, param_env, ty)
tcx.instantiate_and_normalize_erasing_regions(self.args, param_env, ty)
}
/// Finds a crate that contains a monomorphization of this instance that
@ -580,7 +580,7 @@ impl<'tcx> Instance<'tcx> {
self.def.has_polymorphic_mir_body().then_some(self.args)
}
pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
pub fn instantiate_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
where
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
{
@ -593,7 +593,7 @@ impl<'tcx> Instance<'tcx> {
}
#[inline(always)]
pub fn subst_mir_and_normalize_erasing_regions<T>(
pub fn instantiate_mir_and_normalize_erasing_regions<T>(
&self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
@ -603,14 +603,14 @@ impl<'tcx> Instance<'tcx> {
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
{
if let Some(args) = self.args_for_mir_body() {
tcx.subst_and_normalize_erasing_regions(args, param_env, v)
tcx.instantiate_and_normalize_erasing_regions(args, param_env, v)
} else {
tcx.normalize_erasing_regions(param_env, v.skip_binder())
}
}
#[inline(always)]
pub fn try_subst_mir_and_normalize_erasing_regions<T>(
pub fn try_instantiate_mir_and_normalize_erasing_regions<T>(
&self,
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
@ -620,7 +620,7 @@ impl<'tcx> Instance<'tcx> {
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
{
if let Some(args) = self.args_for_mir_body() {
tcx.try_subst_and_normalize_erasing_regions(args, param_env, v)
tcx.try_instantiate_and_normalize_erasing_regions(args, param_env, v)
} else {
tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
}

View File

@ -134,8 +134,9 @@ impl<'tcx> TyCtxt<'tcx> {
/// in-scope substitutions and then normalizing any associated
/// types.
/// Panics if normalization fails. In case normalization might fail
/// use `try_subst_and_normalize_erasing_regions` instead.
pub fn subst_and_normalize_erasing_regions<T>(
/// use `try_instantiate_and_normalize_erasing_regions` instead.
#[instrument(level = "debug", skip(self))]
pub fn instantiate_and_normalize_erasing_regions<T>(
self,
param_args: GenericArgsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>,
@ -144,22 +145,16 @@ impl<'tcx> TyCtxt<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
debug!(
"subst_and_normalize_erasing_regions(\
param_args={:?}, \
value={:?}, \
param_env={:?})",
param_args, value, param_env,
);
let substituted = value.instantiate(self, param_args);
self.normalize_erasing_regions(param_env, substituted)
}
/// Monomorphizes a type from the AST by first applying the
/// in-scope substitutions and then trying to normalize any associated
/// types. Contrary to `subst_and_normalize_erasing_regions` this does
/// types. Contrary to `instantiate_and_normalize_erasing_regions` this does
/// not assume that normalization succeeds.
pub fn try_subst_and_normalize_erasing_regions<T>(
#[instrument(level = "debug", skip(self))]
pub fn try_instantiate_and_normalize_erasing_regions<T>(
self,
param_args: GenericArgsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>,
@ -168,13 +163,6 @@ impl<'tcx> TyCtxt<'tcx> {
where
T: TypeFoldable<TyCtxt<'tcx>>,
{
debug!(
"subst_and_normalize_erasing_regions(\
param_args={:?}, \
value={:?}, \
param_env={:?})",
param_args, value, param_env,
);
let substituted = value.instantiate(self, param_args);
self.try_normalize_erasing_regions(param_env, substituted)
}

View File

@ -193,7 +193,7 @@ impl<'tcx> Inliner<'tcx> {
return Err("optimization fuel exhausted");
}
let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions(
let Ok(callee_body) = callsite.callee.try_instantiate_mir_and_normalize_erasing_regions(
self.tcx,
self.param_env,
ty::EarlyBinder::bind(callee_body.clone()),
@ -481,9 +481,10 @@ impl<'tcx> Inliner<'tcx> {
work_list.push(target);
// If the place doesn't actually need dropping, treat it like a regular goto.
let ty = callsite
.callee
.subst_mir(self.tcx, ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty));
let ty = callsite.callee.instantiate_mir(
self.tcx,
ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty),
);
if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind {
work_list.push(unwind);
}
@ -650,7 +651,7 @@ impl<'tcx> Inliner<'tcx> {
// Copy only unevaluated constants from the callee_body into the caller_body.
// Although we are only pushing `ConstKind::Unevaluated` consts to
// `required_consts`, here we may not only have `ConstKind::Unevaluated`
// because we are calling `subst_and_normalize_erasing_regions`.
// because we are calling `instantiate_and_normalize_erasing_regions`.
caller_body.required_consts.extend(
callee_body.required_consts.iter().copied().filter(|&ct| match ct.const_ {
Const::Ty(_) => {
@ -811,9 +812,10 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
match terminator.kind {
TerminatorKind::Drop { ref place, unwind, .. } => {
// If the place doesn't actually need dropping, treat it like a regular goto.
let ty = self
.instance
.subst_mir(tcx, ty::EarlyBinder::bind(&place.ty(self.callee_body, tcx).ty));
let ty = self.instance.instantiate_mir(
tcx,
ty::EarlyBinder::bind(&place.ty(self.callee_body, tcx).ty),
);
if ty.needs_drop(tcx, self.param_env) {
self.cost += CALL_PENALTY;
if let UnwindAction::Cleanup(_) = unwind {
@ -824,7 +826,8 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
}
}
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty()));
let fn_ty =
self.instance.instantiate_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty()));
self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
// Don't give intrinsics the extra penalty for calls
INSTR_COST

View File

@ -44,7 +44,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
) -> bool {
trace!(%caller);
for &(callee, args) in tcx.mir_inliner_callees(caller.def) {
let Ok(args) = caller.try_subst_mir_and_normalize_erasing_regions(
let Ok(args) = caller.try_instantiate_mir_and_normalize_erasing_regions(
tcx,
param_env,
ty::EarlyBinder::bind(args),

View File

@ -606,7 +606,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
T: TypeFoldable<TyCtxt<'tcx>>,
{
debug!("monomorphize: self.instance={:?}", self.instance);
self.instance.subst_mir_and_normalize_erasing_regions(
self.instance.instantiate_mir_and_normalize_erasing_regions(
self.tcx,
ty::ParamEnv::reveal_all(),
ty::EarlyBinder::bind(value),

View File

@ -647,7 +647,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
// parameters, but the self-type of their impl block do will fail to normalize.
if !tcx.sess.opts.unstable_opts.polymorphize || !instance.has_param() {
// This is a method within an impl, find out what the self-type is:
let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
let impl_self_ty = tcx.instantiate_and_normalize_erasing_regions(
instance.args,
ty::ParamEnv::reveal_all(),
tcx.type_of(impl_def_id),

View File

@ -26,12 +26,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In
let ClosureSizeProfileData { before_feature_tys, after_feature_tys } =
typeck_results.closure_size_eval[&closure_def_id];
let before_feature_tys = tcx.subst_and_normalize_erasing_regions(
let before_feature_tys = tcx.instantiate_and_normalize_erasing_regions(
closure_instance.args,
param_env,
ty::EarlyBinder::bind(before_feature_tys),
);
let after_feature_tys = tcx.subst_and_normalize_erasing_regions(
let after_feature_tys = tcx.instantiate_and_normalize_erasing_regions(
closure_instance.args,
param_env,
ty::EarlyBinder::bind(after_feature_tys),

View File

@ -401,7 +401,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
= get_callee_generic_args_and_args(cx, parent_expr)
{
// FIXME: the `instantiate_identity()` below seems incorrect, since we eventually
// call `tcx.try_subst_and_normalize_erasing_regions` further down
// call `tcx.try_instantiate_and_normalize_erasing_regions` further down
// (i.e., we are explicitly not in the identity context).
let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder();
if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
@ -452,7 +452,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
let output_ty = fn_sig.output();
if output_ty.contains(*param_ty) {
if let Ok(new_ty) = cx.tcx.try_subst_and_normalize_erasing_regions(
if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions(
new_subst, cx.param_env, EarlyBinder::bind(output_ty)) {
expr = parent_expr;
ty = new_ty;