Introduce a #[doc(normalize::consts = ...)] attribute controlling how constant expressions are rendered by rustdoc.
Motivation
Different crates and items have conflicting requirements for their constants. For some, the exact value of a constant is platform dependant. For others, constant folding obsurces the meaning of values. Hovever, [showing a constant as written may leak implementation details], and in some cases, there is no possible value that would be meaningful to the user of the library.
Guide-level explanation
The #[doc(normalize::consts)] attribute can be placed on any item to control how contained constant expressions are displayed in rustdoc-generated documentation.
#[doc(normalize::consts = "fold")]will show them in their fully-evaluated state.#[doc(normalize::consts = "expr")]will show them as-written.#[doc(normalize::consts = "hide")]will cause constant expressions to be replaced with_or not shown at all.
Reference-level explanation
The Attribute
The #[doc(normalize::consts)] attribute determines how constant expressions (constexprs) are rendered by rustdoc.
When applied to any item (including the top-level module within a crate, or impl blocks), it affects all constexprs within that item, and within all childern of that item.
Whenever multiple such attributes would take effect, the innermost attribute takes priority.
constexprs affected include:
- the RHS of
constitems - the RHS of
staticitems - const generics in type aliases
Interaction with #[doc(inline)]
When an item is inlined, it is rendered as if it had been defined in the crate it is being inlined into.
This means that if the doc(normalize::consts) modes of the source and destination crate do not match, an inlined item will always be rendered with the mode from the destination crate.
The Values
"fold"
The current default. Rustdoc will evaluate the constexpr and print it in its fully evaluated form, as if the constexpr was written as a literal.
Numbers will be printed in base 10.
"expr"
Rustdoc will print the constexpr as-written.
If the constexpr contains private identifiers, they will be exposed, so library authors should take care when using this mode.
"hide"
This will cause constants and statics to display without any value, as if the value was unrenderable (see ONCE_INIT), and will cause other constant expressions–such as generic const parameters–to be rendered as _.
Drawbacks
Rustdoc does not currently have the ability to show all constants as-written, namely in the case of inlined re-exports from other crates.
Rationale and alternatives
- The attribute is named
constsand notconstto avoid using keywords in attributes - A key-value format is used instead of a directive system like
doc(fold)to allow multiple states without polluting the doc attribute namespace. - The
normalize::prefix is used because of how const normalization paralells type normalization, and to improve discoverability via search engines if someone finds it in an unfamiliar codebase.
Prior art
- RFC 3631 for an attribute that affects the rendering of child items in a nesting way.
Unresolved questions
- What should be happen rustdoc cannot format a constant as requested?
- How should structs be handled in
"expr"mode? - Are there any other constants that show up in items that this should affect?
- How desirable is the hiding of generic const parameters?
Future possibilities
#[doc(normalize::types)]to control normalization of types.- Controlling the base of folded integer literals.
- Allowing the attribute on individual constant expressions, such as if a type alias has multible const generics that should be rendered differntly.
- Seperatly specifying the rendering for different categories of constant expressions, such as declaring that only
staticitems should have their value hidden. - Control formatting of expression (collapsing/adding whitespace, etc.)