Repository: rust
Issue: rustdoc: rich-text and visibility-aware formatting for constant values
Labels: T-rustdoc,C-enhancement,A-rustdoc-ui

While _types_ in rustdoc are richly formatted using HTML (most notably for hyperlinks to definitions),
_constant expressions_ and _values_ do not enjoy any such treatment and are printed as plain text (or
sometimes even entirely omitted from the documentation).
With the continuously growing language support for “`const`” (`const fn`, const generics, `adt_const_params`,
`generic_const_exprs`, `const_trait_impl`) which allows ever-more-complex constant expressions in
more and more places, it seems very fitting to improve rustdoc's output to help users navigate this complexity.

I propose the following:

* We start showing the constant value of free const items no matter their type. At present, only integers, bools and string literals are displayed.
* We try to use constant values as returned by `tcx.const_eval_poly` as much as possible for pretty-printing and only fall back on `hir::Expr` (unevaluated expressions) as a last resort. Currently for free and assoc. consts, rustdoc evaluates arbitrary const expressions of any type (arbitrary ADTs) but **throws away** the result if the type is not an integer (or similar) and instead prints the unevaluated expression.
* We try to evaluate const _arguments_ and pretty-print the const value. Right now, we just print their unevaluated form, a `hir::Expr`.
* Regarding the formatting / pretty-printing of const values ([`ConstValue`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/interpret/enum.ConstValue.html) / `ValTree`s eventually (?)):
  * We print struct and enum literals (as one would expect). Examples: `S { f: 0 }`, `Ok(())`
  * However, we also **hide private and `doc(hidden)`** fields.
    In non-tuple structs, we skip those fields and add the symbol `..` (mirroring the syntax of struct patterns).
    In tuple structs, we replace them with `_` (just how it's already done today in the code blocks at the top of tuple struct pages)
  * We make paths and struct fields **hyperlinks** to their definition.
  * We print a placeholder like `[/* N elements */]` for large arrays to not clutter the documentation
  * We print a placeholder like maybe `/* large string */` for large strings
  * ( Maybe we should also introduce a max-depth parameter similar to the one rustdoc has for types )

Unfortunately rustdoc's current reliance on `const_eval_poly` means that in a quite a lot of cases – namely those where the const expr contains type or const parameters (including the implicit type parameter `Self`) –, we aren't gonna get the benefits of this proposed richer pretty-printing since the evaluation will fail on those with the error _“too generic“_ and we'll have to fall back on printing the unevaluated `hir::Expr`. This is a known limitation of rustdoc and tracked in #82852.

Parts of this proposal aim to solve #97933 _properly_ whereas #98814 is but a hotfix.
I have already partially implemented this proposal in a local patch that is yet to be published as a PR. You can get a visual taste of it below:

| Stable Rustdoc Output | Nightly Rustdoc Output (#98814) | WIP Implementation of this Proposal |
|---|---|---|
| ![ppconst_stable](https://user-images.githubusercontent.com/14913065/177327525-0311ba8a-bff4-4063-be83-06cdfe7c3da2.png) | ![ppconst_after_hotfix](https://user-images.githubusercontent.com/14913065/177325706-984c77b8-c6d9-47f1-abd7-78a20bbe634c.png) | ![ppconst_linkified](https://user-images.githubusercontent.com/14913065/177325632-796f9f74-0edc-43ed-89c9-985e0157f712.png)  |

@rustbot label T-rustdoc A-rustdoc-ui C-enhancement
@rustbot claim

<!-- TRIAGEBOT_START -->

<!-- TRIAGEBOT_ASSIGN_START -->

<!-- TRIAGEBOT_ASSIGN_DATA_START$${"user":"fmease"}$$TRIAGEBOT_ASSIGN_DATA_END -->

<!-- TRIAGEBOT_ASSIGN_END -->
<!-- TRIAGEBOT_END -->