Although creating a doc attribute directly from a stringify! (or concat!) does not work, i.e.,
#[doc = stringify!(Fails)]
pub enum Fails {}
fails with
error: unexpected token: `stringify`
it is possible to use a macro in some situations. For example, this code compiles correctly
macro_rules! working {
($doc:expr, $id:ident) => {
#[doc = $doc]
pub enum $id {}
}
}
working!(stringify!(Working), Working);
fn main() { }
and rustdoc creates the correct documentation.
macro_rules! bug_helper {
(#[$attr:meta] $id:ident) => {
#[$attr]
pub enum $id {}
}
}
macro_rules! bug {
($doc:expr, $id:ident) => {
bug_helper! { #[doc = $doc] $id }
}
}
bug!(stringify!(Bug), Bug);
fn main() { }
The error message is similar to the one at the top of this report.
error: unexpected token: `stringify!(Bug)`
If the stringify!(Bug) is replaced with "Bug", the code compiles correctly.
All of the above holds true if you replace stringify! with concat!.
I'd expect the second and third code samples above to either both produce an error message or neither. (Preferably, neither.)
Both stable (rustc 1.27.2 (58cc626de 2018-07-18)) and nightly (rustc 1.29.0-nightly (874dec25e 2018-07-21)) have the same behavior.
For anyone else coming across this, I've found the following macro to work well as a workaround:
/// Declares an item with a doc attribute computed by some macro expression.
/// This allows documentation to be dynamically generated based on input.
/// Necessary to work around https://github.com/rust-lang/rust/issues/52607.
macro_rules! calculated_doc {
(
$(
#[doc = $doc:expr]
$thing:item
)*
) => (
$(
#[doc = $doc]
$thing
)*
);
}
This is definitely exploiting compiler behavior, but I'd at least like to believe that the behavior is caused by some fixed macro expansion order which won't change backwards-incompatibly.
Has there been any progress on this?
I've got a macro that automates the writing of getters and setters for an entity's components in an ECS-style system, and being able to give them the equivalent of /// Gets a reference to the [`Window`]'s [`Viewport`] component. would be awesome.
cc https://github.com/rust-lang/rust/pull/67121 "[experiment] Expand macros in inert key-value attributes"
Most helpful comment
For anyone else coming across this, I've found the following macro to work well as a workaround:
This is definitely exploiting compiler behavior, but I'd at least like to believe that the behavior is caused by some fixed macro expansion order which won't change backwards-incompatibly.