Change:
} // Look for equality predicates on associated types that can be merged into <del> // general bound predicates </del> <ins> // general bound predicates. </ins> equalities.retain(|&(ref lhs, ref rhs)| { <del> let Some((self_, trait_did, name)) = lhs.projection() else { return true; }; let clean::Generic(generic) = self_ else { return true }; let Some((bounds, _)) = params.get_mut(generic) else { return true }; </del> <ins> let Some((ty, trait_did, name)) = lhs.projection() else { return true; }; // FIXME(fmease): We don't handle HRTBs correctly here. //                Pass `_bound_params` (higher-rank lifetimes) to a modified version of //                `merge_bounds`. That vector is currently always empty though since we //                don't keep track of late-bound lifetimes when cleaning projection //                predicates to cleaned equality predicates while we should first query //                them with `collect_referenced_late_bound_regions` and then store them //                (or something similar). For prior art, see `clean::auto_trait`. let Some((bounds, _bound_params)) = tybounds.get_mut(ty) else { return true }; </ins> merge_bounds(cx, bounds, trait_did, name, rhs) });

Discussion:
<!-- Thank you for finding a documentation problem! Documentation problems might be grammatical issues, typos, or unclear wording, please provide details regarding the documentation including where it is present. Note: If your issue is for one of these, please use their dedicated issue tracker instead: The Rust Book: Rust by Example: The Edition Guide: The Cargo Book: The Clippy Book: The Reference: The Rustonomicon: The Embedded Book: All other documentation issues should be filed here. Or, if you find an issue related to rustdoc (e.g. doctest, rustdoc UI), please use the bug report or blank issue template instead. -- The definition of the trait looks like: Rustdoc renders this as: This makes the trait bound for the associated type verbose and cryptic. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
label -A-docs C-bug T-rustdoc A-rustdoc-ui A-associated-items
I did a quick investigation: This reproduces on stable and nightly but only if the corresponding trait comes from an extern crate (which is the case with & ). Thus marking this issue as label A-cross-crate-reexports Minimal reproducer: claim
Highly related to / “duplicate” of although the latter is quite outdated.

Currently on nightly the declaration for looks like: ! While the actual declaration with attributes stripped is: Previously up till 1.48.0 this rendered as: ! Which is not great, but at least it has the information there. I tried to identify the PR which changed this in 1.49.0, but skimming the list from a few search queries none of them stood out to me. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
Rendering the declaration without the attributes and outside core/std works just fine: !
Ooooh, it works on that it has this issue. Similarly on 1.48.0 showed the associated type bound nicely, only showed it as a clause.
I may have found the reason why we are skipping the associated type binding. So when an external item (in our case an associated type) gets documented it goes through which then goes through this visitor: Further down we get to: which produces (for the associated item): Then produces: <details<summaryOutput</summary</detailsThe last boils down to which gets discarded further down here (in a operation): Afaics, the reason the unexported trait gets properly "documented" is because a different code path is run which doesn't involve clean on a .
label A-cross-crate-reexports A-associated-items Update: The output is still incorrect but it now looks like this: claim

The documentation for is inconsistent in how it shows the constraints. The actual trait declaration looks like this: The matches this declaration as of 1.49.0-nightly ( 2020-10-08). This is good. However, the shows no constraints at all: The is even weirder, using an equality constraint that's not supported (), and this goes all the way back to . <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
This is the relevant code for traits: This is the relevant code for trait bounds: After that it goes into and I'm not sure where it goes.
Well. I think I found the issue.
Hmm, changing that didn't help - it's always , at least when documenting .
The bounds passed to  are incorrect across crates. Here they are for the original crate: and for the re-export: In particular note that is completely empty.
This looks like the culprit: is the bindings.
This needs larger refactors to rustdoc than I'm comfortable making. is , but the only way to construct those is through which works on the hir, not s, and the HIR is not preserved across crates. Maybe is interested in refactoring this? ;)
Update: The current nightly output is still incorrect: I am already working on a fix and I have already assigned myself to the duplicates of this issue ( and ). claim
Awesome, thanks!