about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-11-13 06:07:27 +0000
committerbors <bors@rust-lang.org>2024-11-13 06:07:27 +0000
commitec239b888f3945a6ce043db639f1741d14f08874 (patch)
tree11b6f9a11c6254b26dcb0f7d3ab35b29c2cd40f5
parent44f233f2519ce5d633c87c38014d03d8a5f0e810 (diff)
parent46603166d7f5cae49f38a3595e2f424a3063c20b (diff)
downloadrust-ec239b888f3945a6ce043db639f1741d14f08874.tar.gz
rust-ec239b888f3945a6ce043db639f1741d14f08874.zip
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
-rw-r--r--src/librustdoc/clean/mod.rs4
-rw-r--r--src/librustdoc/clean/utils.rs40
2 files changed, 19 insertions, 25 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 6b6142a6eaa..15f75384b89 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -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)
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 560831197f0..ec41ad0e8e3 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -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>(