refactor(rustc_middle): Substs -> GenericArg
This commit is contained in:
parent
df5c2cf9bc
commit
e55583c4b8
466 changed files with 4574 additions and 4604 deletions
|
@ -1,7 +1,7 @@
|
|||
use crate::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use crate::ty::print::{FmtPrinter, Printer};
|
||||
use crate::ty::{self, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
|
||||
use crate::ty::{EarlyBinder, InternalSubsts, SubstsRef, TypeVisitableExt};
|
||||
use crate::ty::{EarlyBinder, GenericArgs, GenericArgsRef, TypeVisitableExt};
|
||||
use rustc_errors::ErrorGuaranteed;
|
||||
use rustc_hir::def::Namespace;
|
||||
use rustc_hir::def_id::{CrateNum, DefId};
|
||||
|
@ -16,13 +16,13 @@ use std::fmt;
|
|||
/// A monomorphized `InstanceDef`.
|
||||
///
|
||||
/// Monomorphization happens on-the-fly and no monomorphized MIR is ever created. Instead, this type
|
||||
/// simply couples a potentially generic `InstanceDef` with some substs, and codegen and const eval
|
||||
/// simply couples a potentially generic `InstanceDef` with some args, and codegen and const eval
|
||||
/// will do all required substitution as they run.
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, Lift, TypeFoldable, TypeVisitable)]
|
||||
pub struct Instance<'tcx> {
|
||||
pub def: InstanceDef<'tcx>,
|
||||
pub substs: SubstsRef<'tcx>,
|
||||
pub args: GenericArgsRef<'tcx>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
|
||||
|
@ -115,7 +115,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.substs, param_env, ty)
|
||||
tcx.subst_and_normalize_erasing_regions(self.args, param_env, ty)
|
||||
}
|
||||
|
||||
/// Finds a crate that contains a monomorphization of this instance that
|
||||
|
@ -139,13 +139,13 @@ impl<'tcx> Instance<'tcx> {
|
|||
}
|
||||
|
||||
// If this a non-generic instance, it cannot be a shared monomorphization.
|
||||
self.substs.non_erasable_generics().next()?;
|
||||
self.args.non_erasable_generics().next()?;
|
||||
|
||||
match self.def {
|
||||
InstanceDef::Item(def) => tcx
|
||||
.upstream_monomorphizations_for(def)
|
||||
.and_then(|monos| monos.get(&self.substs).cloned()),
|
||||
InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.substs),
|
||||
.and_then(|monos| monos.get(&self.args).cloned()),
|
||||
InstanceDef::DropGlue(_, Some(_)) => tcx.upstream_drop_glue_for(self.args),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -265,8 +265,8 @@ 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 `substs` from `Instance` (see
|
||||
/// `Instance::substs_for_mir_body`).
|
||||
/// by its users (e.g. codegen or miri) by substituting 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.
|
||||
|
@ -294,10 +294,10 @@ fn fmt_instance(
|
|||
type_length: rustc_session::Limit,
|
||||
) -> fmt::Result {
|
||||
ty::tls::with(|tcx| {
|
||||
let substs = tcx.lift(instance.substs).expect("could not lift for printing");
|
||||
let args = tcx.lift(instance.args).expect("could not lift for printing");
|
||||
|
||||
let s = FmtPrinter::new_with_limit(tcx, Namespace::ValueNS, type_length)
|
||||
.print_def_path(instance.def_id(), substs)?
|
||||
.print_def_path(instance.def_id(), args)?
|
||||
.into_buffer();
|
||||
f.write_str(&s)
|
||||
})?;
|
||||
|
@ -333,18 +333,18 @@ impl<'tcx> fmt::Display for Instance<'tcx> {
|
|||
}
|
||||
|
||||
impl<'tcx> Instance<'tcx> {
|
||||
pub fn new(def_id: DefId, substs: SubstsRef<'tcx>) -> Instance<'tcx> {
|
||||
pub fn new(def_id: DefId, args: GenericArgsRef<'tcx>) -> Instance<'tcx> {
|
||||
assert!(
|
||||
!substs.has_escaping_bound_vars(),
|
||||
"substs of instance {:?} not normalized for codegen: {:?}",
|
||||
!args.has_escaping_bound_vars(),
|
||||
"args of instance {:?} not normalized for codegen: {:?}",
|
||||
def_id,
|
||||
substs
|
||||
args
|
||||
);
|
||||
Instance { def: InstanceDef::Item(def_id), substs }
|
||||
Instance { def: InstanceDef::Item(def_id), args }
|
||||
}
|
||||
|
||||
pub fn mono(tcx: TyCtxt<'tcx>, def_id: DefId) -> Instance<'tcx> {
|
||||
let substs = InternalSubsts::for_item(tcx, def_id, |param, _| match param.kind {
|
||||
let args = GenericArgs::for_item(tcx, def_id, |param, _| match param.kind {
|
||||
ty::GenericParamDefKind::Lifetime => tcx.lifetimes.re_erased.into(),
|
||||
ty::GenericParamDefKind::Type { .. } => {
|
||||
bug!("Instance::mono: {:?} has type parameters", def_id)
|
||||
|
@ -354,7 +354,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
}
|
||||
});
|
||||
|
||||
Instance::new(def_id, substs)
|
||||
Instance::new(def_id, args)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -362,7 +362,7 @@ impl<'tcx> Instance<'tcx> {
|
|||
self.def.def_id()
|
||||
}
|
||||
|
||||
/// Resolves a `(def_id, substs)` pair to an (optional) instance -- most commonly,
|
||||
/// Resolves a `(def_id, args)` pair to an (optional) instance -- most commonly,
|
||||
/// this is used to find the precise code that will run for a trait method invocation,
|
||||
/// if known.
|
||||
///
|
||||
|
@ -390,29 +390,29 @@ impl<'tcx> Instance<'tcx> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Result<Option<Instance<'tcx>>, ErrorGuaranteed> {
|
||||
// All regions in the result of this query are erased, so it's
|
||||
// fine to erase all of the input regions.
|
||||
|
||||
// HACK(eddyb) erase regions in `substs` first, so that `param_env.and(...)`
|
||||
// HACK(eddyb) erase regions in `args` first, so that `param_env.and(...)`
|
||||
// below is more likely to ignore the bounds in scope (e.g. if the only
|
||||
// generic parameters mentioned by `substs` were lifetime ones).
|
||||
let substs = tcx.erase_regions(substs);
|
||||
tcx.resolve_instance(tcx.erase_regions(param_env.and((def_id, substs))))
|
||||
// generic parameters mentioned by `args` were lifetime ones).
|
||||
let args = tcx.erase_regions(args);
|
||||
tcx.resolve_instance(tcx.erase_regions(param_env.and((def_id, args))))
|
||||
}
|
||||
|
||||
pub fn expect_resolve(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Instance<'tcx> {
|
||||
match ty::Instance::resolve(tcx, param_env, def_id, substs) {
|
||||
match ty::Instance::resolve(tcx, param_env, def_id, args) {
|
||||
Ok(Some(instance)) => instance,
|
||||
instance => bug!(
|
||||
"failed to resolve instance for {}: {instance:#?}",
|
||||
tcx.def_path_str_with_substs(def_id, substs)
|
||||
tcx.def_path_str_with_args(def_id, args)
|
||||
),
|
||||
}
|
||||
}
|
||||
|
@ -421,12 +421,12 @@ impl<'tcx> Instance<'tcx> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Option<Instance<'tcx>> {
|
||||
debug!("resolve(def_id={:?}, substs={:?})", def_id, substs);
|
||||
debug!("resolve(def_id={:?}, args={:?})", def_id, args);
|
||||
// Use either `resolve_closure` or `resolve_for_vtable`
|
||||
assert!(!tcx.is_closure(def_id), "Called `resolve_for_fn_ptr` on closure: {:?}", def_id);
|
||||
Instance::resolve(tcx, param_env, def_id, substs).ok().flatten().map(|mut resolved| {
|
||||
Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
|
||||
match resolved.def {
|
||||
InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => {
|
||||
debug!(" => fn pointer created for function with #[track_caller]");
|
||||
|
@ -447,18 +447,18 @@ impl<'tcx> Instance<'tcx> {
|
|||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: SubstsRef<'tcx>,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Option<Instance<'tcx>> {
|
||||
debug!("resolve_for_vtable(def_id={:?}, substs={:?})", def_id, substs);
|
||||
let fn_sig = tcx.fn_sig(def_id).subst_identity();
|
||||
debug!("resolve_for_vtable(def_id={:?}, args={:?})", def_id, args);
|
||||
let fn_sig = tcx.fn_sig(def_id).instantiate_identity();
|
||||
let is_vtable_shim = !fn_sig.inputs().skip_binder().is_empty()
|
||||
&& fn_sig.input(0).skip_binder().is_param(0)
|
||||
&& tcx.generics_of(def_id).has_self;
|
||||
if is_vtable_shim {
|
||||
debug!(" => associated item with unsizeable self: Self");
|
||||
Some(Instance { def: InstanceDef::VTableShim(def_id), substs })
|
||||
Some(Instance { def: InstanceDef::VTableShim(def_id), args })
|
||||
} else {
|
||||
Instance::resolve(tcx, param_env, def_id, substs).ok().flatten().map(|mut resolved| {
|
||||
Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
|
||||
match resolved.def {
|
||||
InstanceDef::Item(def) => {
|
||||
// We need to generate a shim when we cannot guarantee that
|
||||
|
@ -489,12 +489,12 @@ impl<'tcx> Instance<'tcx> {
|
|||
{
|
||||
if tcx.is_closure(def) {
|
||||
debug!(" => vtable fn pointer created for closure with #[track_caller]: {:?} for method {:?} {:?}",
|
||||
def, def_id, substs);
|
||||
def, def_id, args);
|
||||
|
||||
// Create a shim for the `FnOnce/FnMut/Fn` method we are calling
|
||||
// - unlike functions, invoking a closure always goes through a
|
||||
// trait.
|
||||
resolved = Instance { def: InstanceDef::ReifyShim(def_id), substs };
|
||||
resolved = Instance { def: InstanceDef::ReifyShim(def_id), args };
|
||||
} else {
|
||||
debug!(
|
||||
" => vtable fn pointer created for function with #[track_caller]: {:?}", def
|
||||
|
@ -518,28 +518,28 @@ impl<'tcx> Instance<'tcx> {
|
|||
pub fn resolve_closure(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: ty::SubstsRef<'tcx>,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
requested_kind: ty::ClosureKind,
|
||||
) -> Option<Instance<'tcx>> {
|
||||
let actual_kind = substs.as_closure().kind();
|
||||
let actual_kind = args.as_closure().kind();
|
||||
|
||||
match needs_fn_once_adapter_shim(actual_kind, requested_kind) {
|
||||
Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, substs),
|
||||
_ => Some(Instance::new(def_id, substs)),
|
||||
Ok(true) => Instance::fn_once_adapter_instance(tcx, def_id, args),
|
||||
_ => Some(Instance::new(def_id, args)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolve_drop_in_place(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> ty::Instance<'tcx> {
|
||||
let def_id = tcx.require_lang_item(LangItem::DropInPlace, None);
|
||||
let substs = tcx.mk_substs(&[ty.into()]);
|
||||
Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, substs)
|
||||
let args = tcx.mk_args(&[ty.into()]);
|
||||
Instance::expect_resolve(tcx, ty::ParamEnv::reveal_all(), def_id, args)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx), ret)]
|
||||
pub fn fn_once_adapter_instance(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
closure_did: DefId,
|
||||
substs: ty::SubstsRef<'tcx>,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
) -> Option<Instance<'tcx>> {
|
||||
let fn_once = tcx.require_lang_item(LangItem::FnOnce, None);
|
||||
let call_once = tcx
|
||||
|
@ -552,30 +552,30 @@ impl<'tcx> Instance<'tcx> {
|
|||
tcx.codegen_fn_attrs(closure_did).flags.contains(CodegenFnAttrFlags::TRACK_CALLER);
|
||||
let def = ty::InstanceDef::ClosureOnceShim { call_once, track_caller };
|
||||
|
||||
let self_ty = Ty::new_closure(tcx, closure_did, substs);
|
||||
let self_ty = Ty::new_closure(tcx, closure_did, args);
|
||||
|
||||
let sig = substs.as_closure().sig();
|
||||
let sig = args.as_closure().sig();
|
||||
let sig =
|
||||
tcx.try_normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), sig).ok()?;
|
||||
assert_eq!(sig.inputs().len(), 1);
|
||||
let substs = tcx.mk_substs_trait(self_ty, [sig.inputs()[0].into()]);
|
||||
let args = tcx.mk_args_trait(self_ty, [sig.inputs()[0].into()]);
|
||||
|
||||
debug!(?self_ty, ?sig);
|
||||
Some(Instance { def, substs })
|
||||
Some(Instance { def, args })
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// values from the substs when monomorphizing the function body. But in the latter case, we
|
||||
/// 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.
|
||||
///
|
||||
/// This function returns `Some(substs)` in the former case and `None` otherwise -- i.e., if
|
||||
/// 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
|
||||
/// codegen.
|
||||
fn substs_for_mir_body(&self) -> Option<SubstsRef<'tcx>> {
|
||||
self.def.has_polymorphic_mir_body().then_some(self.substs)
|
||||
fn args_for_mir_body(&self) -> Option<GenericArgsRef<'tcx>> {
|
||||
self.def.has_polymorphic_mir_body().then_some(self.args)
|
||||
}
|
||||
|
||||
pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
|
||||
|
@ -583,10 +583,10 @@ impl<'tcx> Instance<'tcx> {
|
|||
T: TypeFoldable<TyCtxt<'tcx>> + Copy,
|
||||
{
|
||||
let v = v.map_bound(|v| *v);
|
||||
if let Some(substs) = self.substs_for_mir_body() {
|
||||
v.subst(tcx, substs)
|
||||
if let Some(args) = self.args_for_mir_body() {
|
||||
v.instantiate(tcx, args)
|
||||
} else {
|
||||
v.subst_identity()
|
||||
v.instantiate_identity()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -600,8 +600,8 @@ impl<'tcx> Instance<'tcx> {
|
|||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
|
||||
{
|
||||
if let Some(substs) = self.substs_for_mir_body() {
|
||||
tcx.subst_and_normalize_erasing_regions(substs, param_env, v)
|
||||
if let Some(args) = self.args_for_mir_body() {
|
||||
tcx.subst_and_normalize_erasing_regions(args, param_env, v)
|
||||
} else {
|
||||
tcx.normalize_erasing_regions(param_env, v.skip_binder())
|
||||
}
|
||||
|
@ -617,14 +617,14 @@ impl<'tcx> Instance<'tcx> {
|
|||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>> + Clone,
|
||||
{
|
||||
if let Some(substs) = self.substs_for_mir_body() {
|
||||
tcx.try_subst_and_normalize_erasing_regions(substs, param_env, v)
|
||||
if let Some(args) = self.args_for_mir_body() {
|
||||
tcx.try_subst_and_normalize_erasing_regions(args, param_env, v)
|
||||
} else {
|
||||
tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a new `Instance` where generic parameters in `instance.substs` are replaced by
|
||||
/// Returns a new `Instance` where generic parameters in `instance.args` are replaced by
|
||||
/// identity parameters if they are determined to be unused in `instance.def`.
|
||||
pub fn polymorphize(self, tcx: TyCtxt<'tcx>) -> Self {
|
||||
debug!("polymorphize: running polymorphization analysis");
|
||||
|
@ -632,18 +632,18 @@ impl<'tcx> Instance<'tcx> {
|
|||
return self;
|
||||
}
|
||||
|
||||
let polymorphized_substs = polymorphize(tcx, self.def, self.substs);
|
||||
debug!("polymorphize: self={:?} polymorphized_substs={:?}", self, polymorphized_substs);
|
||||
Self { def: self.def, substs: polymorphized_substs }
|
||||
let polymorphized_args = polymorphize(tcx, self.def, self.args);
|
||||
debug!("polymorphize: self={:?} polymorphized_args={:?}", self, polymorphized_args);
|
||||
Self { def: self.def, args: polymorphized_args }
|
||||
}
|
||||
}
|
||||
|
||||
fn polymorphize<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
instance: ty::InstanceDef<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> SubstsRef<'tcx> {
|
||||
debug!("polymorphize({:?}, {:?})", instance, substs);
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> GenericArgsRef<'tcx> {
|
||||
debug!("polymorphize({:?}, {:?})", instance, args);
|
||||
let unused = tcx.unused_generic_params(instance);
|
||||
debug!("polymorphize: unused={:?}", unused);
|
||||
|
||||
|
@ -653,9 +653,9 @@ fn polymorphize<'tcx>(
|
|||
// multiple mono items (and eventually symbol clashes).
|
||||
let def_id = instance.def_id();
|
||||
let upvars_ty = if tcx.is_closure(def_id) {
|
||||
Some(substs.as_closure().tupled_upvars_ty())
|
||||
Some(args.as_closure().tupled_upvars_ty())
|
||||
} else if tcx.type_of(def_id).skip_binder().is_generator() {
|
||||
Some(substs.as_generator().tupled_upvars_ty())
|
||||
Some(args.as_generator().tupled_upvars_ty())
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
@ -674,22 +674,22 @@ fn polymorphize<'tcx>(
|
|||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
debug!("fold_ty: ty={:?}", ty);
|
||||
match *ty.kind() {
|
||||
ty::Closure(def_id, substs) => {
|
||||
let polymorphized_substs =
|
||||
polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs);
|
||||
if substs == polymorphized_substs {
|
||||
ty::Closure(def_id, args) => {
|
||||
let polymorphized_args =
|
||||
polymorphize(self.tcx, ty::InstanceDef::Item(def_id), args);
|
||||
if args == polymorphized_args {
|
||||
ty
|
||||
} else {
|
||||
Ty::new_closure(self.tcx, def_id, polymorphized_substs)
|
||||
Ty::new_closure(self.tcx, def_id, polymorphized_args)
|
||||
}
|
||||
}
|
||||
ty::Generator(def_id, substs, movability) => {
|
||||
let polymorphized_substs =
|
||||
polymorphize(self.tcx, ty::InstanceDef::Item(def_id), substs);
|
||||
if substs == polymorphized_substs {
|
||||
ty::Generator(def_id, args, movability) => {
|
||||
let polymorphized_args =
|
||||
polymorphize(self.tcx, ty::InstanceDef::Item(def_id), args);
|
||||
if args == polymorphized_args {
|
||||
ty
|
||||
} else {
|
||||
Ty::new_generator(self.tcx, def_id, polymorphized_substs, movability)
|
||||
Ty::new_generator(self.tcx, def_id, polymorphized_args, movability)
|
||||
}
|
||||
}
|
||||
_ => ty.super_fold_with(self),
|
||||
|
@ -697,7 +697,7 @@ fn polymorphize<'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
InternalSubsts::for_item(tcx, def_id, |param, _| {
|
||||
GenericArgs::for_item(tcx, def_id, |param, _| {
|
||||
let is_unused = unused.is_unused(param.index);
|
||||
debug!("polymorphize: param={:?} is_unused={:?}", param, is_unused);
|
||||
match param.kind {
|
||||
|
@ -706,7 +706,7 @@ fn polymorphize<'tcx>(
|
|||
// ..and has upvars..
|
||||
has_upvars &&
|
||||
// ..and this param has the same type as the tupled upvars..
|
||||
upvars_ty == Some(substs[param.index as usize].expect_ty()) => {
|
||||
upvars_ty == Some(args[param.index as usize].expect_ty()) => {
|
||||
// ..then double-check that polymorphization marked it used..
|
||||
debug_assert!(!is_unused);
|
||||
// ..and polymorphize any closures/generators captured as upvars.
|
||||
|
@ -725,7 +725,7 @@ fn polymorphize<'tcx>(
|
|||
tcx.mk_param_from_def(param),
|
||||
|
||||
// Otherwise, use the parameter as before.
|
||||
_ => substs[param.index as usize],
|
||||
_ => args[param.index as usize],
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue