Code
I tried this code:
#![crate_type = "lib"]
pub trait Bound<const R: usize, const C: usize> {}
macro_rules! cartesian_bounds {
({$($item:tt)*}, $dimensions:tt) => {
cartesian_bounds!(@row {$($item)*}, $dimensions, $dimensions);
};
(@row {$($item:tt)*}, [], $columns:tt) => {
$($item)* {}
};
(@row {$($item:tt)*}, [$row:tt $(, $rows:tt)*], $columns:tt) => {
cartesian_bounds!(@emit {$($item)*}, $row, [$($rows),*], $columns);
};
(@emit {$($item:tt)*}, $row:tt, $rows:tt, [$($column:tt),*]) => {
cartesian_bounds!(@row {
$($item)* $(+ Bound<$row, $column>)*
}, $rows, [$($column),*]);
};
}
cartesian_bounds!({
pub trait Example<const N: usize>: Sized
}, [1, N]);
Then I generated the documentation and opened doc/rustdoc_macro_metavariable_repro/trait.Example.html:
rustdoc +nightly --edition=2024 rustdoc_macro_metavariable_repro.rs
Expected behavior
The trait declaration should contain the expanded const generic arguments:
pub trait Example<const N: usize>:
Sized
+ Bound<1, 1>
+ Bound<1, N>
+ Bound<N, 1>
+ Bound<N, N>
{ }
This agrees with the compiler's expanded output from:
rustc +nightly --edition=2024 -Zunpretty=expanded rustdoc_macro_metavariable_repro.rs
Actual behavior
rustdoc renders the metavariable names for literal arguments while resolved const parameters are rendered correctly:
pub trait Example<const N: usize>:
Sized
+ Bound<$row, $column>
+ Bound<$row, N>
+ Bound<N, $column>
+ Bound<N, N>
{ }
The generated crate is valid and the macro expansion used for compilation contains Bound<1, 1>, so this appears to affect only rustdoc's rendering of the declaration.
Changing the repeated captures from tt fragments to expr fragments makes rustdoc render the literals correctly. Moving [1, N] into the macro definition also avoids the problem. These changes appear to alter the spans carried by the expanded literal const arguments.
Version
rustc 1.99.0-nightly (ad3d0bc14 2026-07-31)
binary: rustc
commit-hash: ad3d0bc141a02cf446e384136d250a1f6950fed5
commit-date: 2026-07-31
host: x86_64-pc-windows-msvc
release: 1.99.0-nightly
LLVM version: 22.1.8
The issue also reproduces with stable rustdoc 1.97.1 (8bab26f4f 2026-07-14).
Code
I tried this code:
Then I generated the documentation and opened
doc/rustdoc_macro_metavariable_repro/trait.Example.html:rustdoc +nightly --edition=2024 rustdoc_macro_metavariable_repro.rsExpected behavior
The trait declaration should contain the expanded const generic arguments:
This agrees with the compiler's expanded output from:
rustc +nightly --edition=2024 -Zunpretty=expanded rustdoc_macro_metavariable_repro.rsActual behavior
rustdoc renders the metavariable names for literal arguments while resolved const parameters are rendered correctly:
The generated crate is valid and the macro expansion used for compilation contains
Bound<1, 1>, so this appears to affect only rustdoc's rendering of the declaration.Changing the repeated captures from
ttfragments toexprfragments makes rustdoc render the literals correctly. Moving[1, N]into the macro definition also avoids the problem. These changes appear to alter the spans carried by the expanded literal const arguments.Version
The issue also reproduces with stable
rustdoc 1.97.1 (8bab26f4f 2026-07-14).