Auto merge of #132886 - fmease:rustdoc-perf-clean-middle-args, r=GuillaumeGomez

[perf] rustdoc: Perform less work when cleaning middle::ty parenthesized generic args

CC #132697. I presume the perf regression it caused (if real) boils down to query invocation overhead, namely of `def_kind` & `trait_def` as we don't seem to be decoding more often from the crate metadata.

I won't try the obvious and reduce the amount of query calls by threading information via params as that would render the code awkward.

So instead I'm simply trying to attack some low-hanging fruits in the vicinity.

---

Previously, we would `clean_middle_generic_args` *unconditionally* inside `clean_middle_generic_args_with_constraints` even though we didn't actually use its result for parenthesized generic args (`Trait(...) -> ...`).

Now, we only call `clean_middle_generic_args` when necessary. Lastly, I've simplified `clean_middle_generic_args_with_constraints`.

---

r? ghost
This commit is contained in:
bors 2024-11-13 06:07:27 +00:00
commit ec239b888f
2 changed files with 19 additions and 25 deletions

View File

@ -2119,7 +2119,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
})
.collect::<Vec<_>>();
let bindings = obj
let constraints = obj
.projection_bounds()
.map(|pb| AssocItemConstraint {
assoc: projection_to_path_segment(
@ -2155,7 +2155,7 @@ pub(crate) fn clean_middle_ty<'tcx>(
.collect();
let late_bound_regions = late_bound_regions.into_iter().collect();
let path = clean_middle_path(cx, did, false, bindings, args);
let path = clean_middle_path(cx, did, false, constraints, args);
bounds.insert(0, PolyTrait { trait_: path, generic_params: late_bound_regions });
DynTrait(bounds, lifetime)

View File

@ -112,7 +112,6 @@ pub(crate) fn clean_middle_generic_args<'tcx>(
return None;
}
// Elide internal host effect args.
let param = generics.param_at(index, cx.tcx);
let arg = ty::Binder::bind_with_vars(arg, bound_vars);
@ -201,35 +200,30 @@ fn clean_middle_generic_args_with_constraints<'tcx>(
cx: &mut DocContext<'tcx>,
did: DefId,
has_self: bool,
constraints: ThinVec<AssocItemConstraint>,
ty_args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
mut constraints: ThinVec<AssocItemConstraint>,
args: ty::Binder<'tcx, GenericArgsRef<'tcx>>,
) -> GenericArgs {
let args = clean_middle_generic_args(cx, ty_args.map_bound(|args| &args[..]), has_self, did);
if cx.tcx.is_trait(did) && cx.tcx.trait_def(did).paren_sugar {
let ty = ty_args
if cx.tcx.is_trait(did)
&& cx.tcx.trait_def(did).paren_sugar
&& let ty::Tuple(tys) = args.skip_binder().type_at(has_self as usize).kind()
{
let inputs = tys
.iter()
.nth(if has_self { 1 } else { 0 })
.unwrap()
.map_bound(|arg| arg.expect_ty());
let inputs =
// The trait's first substitution is the one after self, if there is one.
match ty.skip_binder().kind() {
ty::Tuple(tys) => tys.iter().map(|t| clean_middle_ty(ty.rebind(t), cx, None, None)).collect::<Vec<_>>().into(),
_ => return GenericArgs::AngleBracketed { args: args.into(), constraints },
};
let output = constraints.into_iter().next().and_then(|binding| match binding.kind {
AssocItemConstraintKind::Equality { term: Term::Type(ty) }
if ty != Type::Tuple(Vec::new()) =>
{
.map(|ty| clean_middle_ty(args.rebind(ty), cx, None, None))
.collect::<Vec<_>>()
.into();
let output = constraints.pop().and_then(|constraint| match constraint.kind {
AssocItemConstraintKind::Equality { term: Term::Type(ty) } if !ty.is_unit() => {
Some(Box::new(ty))
}
_ => None,
});
GenericArgs::Parenthesized { inputs, output }
} else {
GenericArgs::AngleBracketed { args: args.into(), constraints }
return GenericArgs::Parenthesized { inputs, output };
}
let args = clean_middle_generic_args(cx, args.map_bound(|args| &args[..]), has_self, did);
GenericArgs::AngleBracketed { args: args.into(), constraints }
}
pub(super) fn clean_middle_path<'tcx>(