← Back to index
PR #3770Work-in-progress preview from an open pull request.View on GitHub ↗
DRAFT
#3770

doc_consts

Authorlolbinarycat
CreatedJan 20 2025
UpdatedJun 4 2025
Rust Issue

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 const items
  • the RHS of static items
  • 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 consts and not const to 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 static items should have their value hidden.
  • Control formatting of expression (collapsing/adding whitespace, etc.)