mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Don't arena-allocate extended generic args
This commit is contained in:
parent
17ec134fa4
commit
4b859e68aa
@ -1908,7 +1908,7 @@ fn normalize<'tcx>(
|
||||
|
||||
fn clean_trait_object_lifetime_bound<'tcx>(
|
||||
region: ty::Region<'tcx>,
|
||||
container: Option<ContainerTy<'tcx>>,
|
||||
container: Option<ContainerTy<'_, 'tcx>>,
|
||||
preds: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Option<Lifetime> {
|
||||
@ -1937,7 +1937,7 @@ fn clean_trait_object_lifetime_bound<'tcx>(
|
||||
|
||||
fn can_elide_trait_object_lifetime_bound<'tcx>(
|
||||
region: ty::Region<'tcx>,
|
||||
container: Option<ContainerTy<'tcx>>,
|
||||
container: Option<ContainerTy<'_, 'tcx>>,
|
||||
preds: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> bool {
|
||||
@ -1984,18 +1984,18 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ContainerTy<'tcx> {
|
||||
pub(crate) enum ContainerTy<'a, 'tcx> {
|
||||
Ref(ty::Region<'tcx>),
|
||||
Regular {
|
||||
ty: DefId,
|
||||
/// The arguments *have* to contain an arg for the self type if the corresponding generics
|
||||
/// contain a self type.
|
||||
args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
|
||||
args: ty::Binder<'tcx, &'a [ty::GenericArg<'tcx>]>,
|
||||
arg: usize,
|
||||
},
|
||||
}
|
||||
|
||||
impl<'tcx> ContainerTy<'tcx> {
|
||||
impl<'tcx> ContainerTy<'_, 'tcx> {
|
||||
fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> {
|
||||
match self {
|
||||
Self::Ref(region) => ObjectLifetimeDefault::Arg(region),
|
||||
@ -2044,7 +2044,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
|
||||
bound_ty: ty::Binder<'tcx, Ty<'tcx>>,
|
||||
cx: &mut DocContext<'tcx>,
|
||||
parent_def_id: Option<DefId>,
|
||||
container: Option<ContainerTy<'tcx>>,
|
||||
container: Option<ContainerTy<'_, 'tcx>>,
|
||||
) -> Type {
|
||||
let bound_ty = normalize(cx, bound_ty).unwrap_or(bound_ty);
|
||||
match *bound_ty.skip_binder().kind() {
|
||||
|
@ -81,7 +81,8 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
|
||||
mut has_self: bool,
|
||||
owner: DefId,
|
||||
) -> Vec<GenericArg> {
|
||||
if args.skip_binder().is_empty() {
|
||||
let (args, bound_vars) = (args.skip_binder(), args.bound_vars());
|
||||
if args.is_empty() {
|
||||
// Fast path which avoids executing the query `generics_of`.
|
||||
return Vec::new();
|
||||
}
|
||||
@ -90,7 +91,7 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
|
||||
let mut elision_has_failed_once_before = false;
|
||||
|
||||
let offset = if has_self { 1 } else { 0 };
|
||||
let mut clean_args = Vec::with_capacity(args.skip_binder().len().saturating_sub(offset));
|
||||
let mut clean_args = Vec::with_capacity(args.len().saturating_sub(offset));
|
||||
|
||||
// If the container is a trait object type, the arguments won't contain the self type but the
|
||||
// generics of the corresponding trait will. In such a case, prepend a dummy self type in order
|
||||
@ -98,16 +99,13 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
|
||||
// instantiate the generic parameter default later.
|
||||
let args = if !has_self && generics.parent.is_none() && generics.has_self {
|
||||
has_self = true;
|
||||
// FIXME(fmease): Don't arena-allocate the args (blocked on further refactorings)!
|
||||
args.map_bound(|args| {
|
||||
&*cx.tcx.arena.alloc_from_iter(
|
||||
[cx.tcx.types.trait_object_dummy_self.into()]
|
||||
.into_iter()
|
||||
.chain(args.iter().copied()),
|
||||
)
|
||||
})
|
||||
[cx.tcx.types.trait_object_dummy_self.into()]
|
||||
.into_iter()
|
||||
.chain(args.iter().copied())
|
||||
.collect::<Vec<_>>()
|
||||
.into()
|
||||
} else {
|
||||
args
|
||||
std::borrow::Cow::from(args)
|
||||
};
|
||||
|
||||
let clean_arg = |(index, arg): (usize, &ty::GenericArg<'tcx>)| match arg.unpack() {
|
||||
@ -116,12 +114,13 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
|
||||
}
|
||||
GenericArgKind::Type(_) if has_self && index == 0 => None,
|
||||
GenericArgKind::Type(ty) => {
|
||||
let ty = ty::Binder::bind_with_vars(ty, bound_vars);
|
||||
|
||||
if !elision_has_failed_once_before
|
||||
&& let Some(default) = generics.param_at(index, cx.tcx).default_value(cx.tcx)
|
||||
{
|
||||
let default = args.map_bound(|args| default.instantiate(cx.tcx, args).expect_ty());
|
||||
|
||||
if can_elide_generic_arg(args.rebind(ty), default) {
|
||||
let default = default.instantiate(cx.tcx, args.as_ref()).expect_ty();
|
||||
if can_elide_generic_arg(ty, ty.rebind(default)) {
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -129,10 +128,14 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
|
||||
}
|
||||
|
||||
Some(GenericArg::Type(clean_middle_ty(
|
||||
args.rebind(ty),
|
||||
ty,
|
||||
cx,
|
||||
None,
|
||||
Some(crate::clean::ContainerTy::Regular { ty: owner, args, arg: index }),
|
||||
Some(crate::clean::ContainerTy::Regular {
|
||||
ty: owner,
|
||||
args: ty.rebind(args.as_ref()),
|
||||
arg: index,
|
||||
}),
|
||||
)))
|
||||
}
|
||||
GenericArgKind::Const(ct) => {
|
||||
@ -142,24 +145,24 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
|
||||
return None;
|
||||
}
|
||||
|
||||
let ct = ty::Binder::bind_with_vars(ct, bound_vars);
|
||||
|
||||
if !elision_has_failed_once_before
|
||||
&& let Some(default) = generics.param_at(index, cx.tcx).default_value(cx.tcx)
|
||||
{
|
||||
let default =
|
||||
args.map_bound(|args| default.instantiate(cx.tcx, args).expect_const());
|
||||
|
||||
if can_elide_generic_arg(args.rebind(ct), default) {
|
||||
let default = default.instantiate(cx.tcx, args.as_ref()).expect_const();
|
||||
if can_elide_generic_arg(ct, ct.rebind(default)) {
|
||||
return None;
|
||||
}
|
||||
|
||||
elision_has_failed_once_before = true;
|
||||
}
|
||||
|
||||
Some(GenericArg::Const(Box::new(clean_middle_const(args.rebind(ct), cx))))
|
||||
Some(GenericArg::Const(Box::new(clean_middle_const(ct, cx))))
|
||||
}
|
||||
};
|
||||
|
||||
clean_args.extend(args.skip_binder().iter().enumerate().rev().filter_map(clean_arg));
|
||||
clean_args.extend(args.iter().enumerate().rev().filter_map(clean_arg));
|
||||
clean_args.reverse();
|
||||
clean_args
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user