Code change:
<ins> #![feature(external_doc)] #![crate_name = "foo"] // @has foo/struct.Example.html // @matches - '//pre[@class="rust rust-example-rendered"]'  //     '(?m)let example = Example::new()n    .first()n    .second()n    .build();Z' /// ```rust /// let example = Example::new() ///     .first() #[cfg_attr(not(feature = "one"), doc = "    .second()")] ///     .build(); /// ``` pub struct Example; // @has foo/struct.F.html // @matches - '//pre[@class="rust rust-example-rendered"]'  //     '(?m)let example = Example::new()n    .first()n    .another()n    .build();Z' ///```rust ///let example = Example::new() ///    .first() #[cfg_attr(not(feature = "one"), doc = "    .another()")] ///    .build(); /// ``` pub struct F; // @has foo/struct.G.html // @matches - '//pre[@class="rust rust-example-rendered"]'  //     '(?m)let example = Example::new()n.first()n    .another()n.build();Z' ///```rust ///let example = Example::new() ///.first() #[cfg_attr(not(feature = "one"), doc = "    .another()")] ///.build(); ///``` pub struct G; // @has foo/struct.H.html // @has - '//div[@class="docblock"]/p' 'no whitespace lol' ///no whitespace #[doc = " lol"] pub struct H; // @has foo/struct.I.html // @matches - '//pre[@class="rust rust-example-rendered"]' '(?m)4 whitespaces!Z' ///     4 whitespaces! #[doc = "something"] pub struct I; // @has foo/struct.J.html // @matches - '//div[@class="docblock"]/p' '(?m)anno whitespacenJust some text.Z' ///a ///no whitespace #[doc(include = "unindent.md")] pub struct J; // @has foo/struct.K.html // @matches - '//pre[@class="rust rust-example-rendered"]' '(?m)4 whitespaces!Z' ///a /// ///    4 whitespaces! /// #[doc(include = "unindent.md")] pub struct K; </ins>

Related discussion:
text: <!-- Thank you for filing a bug report! Please provide a short summary of the bug, along with any information you feel relevant to replicating the bug. --I tried this code: /// let example = Example::new() /// .first("hello") #[cfgattr(not(feature = "one"), doc = " .second("hello")n")] /// .third("hello") /// .build(); /// with I expected to see this: ! Instead, this happened: ! <!-- If you're using the stable version of the compiler, you should also check if the bug also exists in the beta or nightly versions. --: running over the code gives me /// let example = Example::new() /// .first("hello") /// .second("hello") /// .third("hello") /// .build(); ///
As explained on discord, <strikethe attributes aren't applied to doc comments</strike(EDIT: they are applied, the problem seems to be that it results in two doc comments for rustdoc). However, your doc comment is split in two so the second half isn't considered as being inside a code block, explaining why you have this display. Even if shows it as one doc comment, rustdoc sees two of them. <strikeMaybe we should add a warning or something that attributes aren't applied to doc comments... What do you think ?</strike
How can an attribute get applied to a doc comment? Both are, under the hood, attributes, no? I would expect that to be equivalent to expecting to only derive Debug if is passed, which is not how that works. I'm guessing what is true is that attributes directly written don't actually merge with -style comments. Potentially relevant: , ,
Simplified reproducer rust //! foo(); #![doc = " bar();"] //! Checking with 1.31.0 it still ignores it (so likely not related), but checking with 1.21.0 (and 1.0.0) it worked as expected, so somewhere within that range (but I don't have any other versions installed at the moment to check).
Compilation broke somewhere between 1.23.0 (works) 1.24.0 (does not work) I tested it with rust //! let x = r#" #![doc = " bar();"] //! "#; //! assert_eq!