Skip to content

Commit

Permalink
Auto merge of #116195 - fmease:rustdoc-investigate-perf-regression, r…
Browse files Browse the repository at this point in the history
…=GuillaumeGomez

rustdoc: speed up processing of cross-crate fns to fix a perf regression

* The first commit doesn't affect perf but get's rid of a `.clone()` and a bunch of lines of code. I can drop it if you'd like me to
* The second commit, *“reduce the amount of `asyncness` query executions”*, addresses the perf regression introduced in #116084

r? `@ghost`
  • Loading branch information
bors committed Sep 30, 2023
2 parents 1770912 + 841bff2 commit 5282e5e
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 27 deletions.
8 changes: 7 additions & 1 deletion src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,13 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
// but shouldn't change any code meaning.
let mut output = clean_middle_ty(sig.output(), cx, None, None);

if let Some(did) = did && cx.tcx.asyncness(did).is_async() {
// If the return type isn't an `impl Trait`, we can safely assume that this
// function isn't async without needing to execute the query `asyncness` at
// all which gives us a noticeable performance boost.
if let Some(did) = did
&& let Type::ImplTrait(_) = output
&& cx.tcx.asyncness(did).is_async()
{
output = output.sugared_async_return_type();
}

Expand Down
35 changes: 9 additions & 26 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1604,14 +1604,16 @@ impl Type {
///
/// This function will panic if the return type does not match the expected sugaring for async
/// functions.
pub(crate) fn sugared_async_return_type(&self) -> Type {
if let Type::ImplTrait(v) = self &&
let [GenericBound::TraitBound(PolyTrait { trait_, .. }, _ )] = &v[..]
pub(crate) fn sugared_async_return_type(self) -> Type {
if let Type::ImplTrait(mut v) = self
&& let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _ )) = v.pop()
&& let Some(segment) = trait_.segments.pop()
&& let GenericArgs::AngleBracketed { mut bindings, .. } = segment.args
&& let Some(binding) = bindings.pop()
&& let TypeBindingKind::Equality { term } = binding.kind
&& let Term::Type(ty) = term
{
let bindings = trait_.bindings().unwrap();
let ret_ty = bindings[0].term();
let ty = ret_ty.ty().expect("unexpected constant in async fn return term");
ty.clone()
ty
} else {
panic!("unexpected async fn return type")
}
Expand Down Expand Up @@ -2189,16 +2191,6 @@ impl Path {
}
})
}

pub(crate) fn bindings(&self) -> Option<&[TypeBinding]> {
self.segments.last().and_then(|seg| {
if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
Some(&**bindings)
} else {
None
}
})
}
}

#[derive(Clone, PartialEq, Eq, Debug, Hash)]
Expand Down Expand Up @@ -2478,15 +2470,6 @@ pub(crate) enum TypeBindingKind {
Constraint { bounds: Vec<GenericBound> },
}

impl TypeBinding {
pub(crate) fn term(&self) -> &Term {
match self.kind {
TypeBindingKind::Equality { ref term } => term,
_ => panic!("expected equality type binding for parenthesized generic args"),
}
}
}

/// The type, lifetime, or constant that a private type alias's parameter should be
/// replaced with when expanding a use of that type alias.
///
Expand Down

0 comments on commit 5282e5e

Please sign in to comment.