about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2025-02-18 18:07:14 +0100
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2025-08-23 00:57:28 +0200
commitf8ce37621ae83f1323a83f833ab2abecdc20a0ba (patch)
tree7ddd757ee755e897d1ab6fa3de58704655bdc2ad
parentba3099f60b25437b7a871a3dfe7aa71bf867cd90 (diff)
downloadrust-f8ce37621ae83f1323a83f833ab2abecdc20a0ba.tar.gz
rust-f8ce37621ae83f1323a83f833ab2abecdc20a0ba.zip
Add new unstable `--generate-macro-expansion` rustdoc command line flag
-rw-r--r--src/librustdoc/config.rs11
-rw-r--r--src/librustdoc/html/highlight.rs25
-rw-r--r--src/librustdoc/html/render/context.rs2
-rw-r--r--src/librustdoc/html/render/span_map.rs10
-rw-r--r--src/librustdoc/lib.rs8
5 files changed, 42 insertions, 14 deletions
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index c52c7236883..450ac04b40d 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -305,6 +305,8 @@ pub(crate) struct RenderOptions {
     pub(crate) parts_out_dir: Option<PathToParts>,
     /// disable minification of CSS/JS
     pub(crate) disable_minification: bool,
+    /// If `true`, HTML source pages will generate the possibility to expand macros.
+    pub(crate) generate_macro_expansion: bool,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -786,6 +788,7 @@ impl Options {
         let show_type_layout = matches.opt_present("show-type-layout");
         let nocapture = matches.opt_present("nocapture");
         let generate_link_to_definition = matches.opt_present("generate-link-to-definition");
+        let generate_macro_expansion = matches.opt_present("generate-macro-expansion");
         let extern_html_root_takes_precedence =
             matches.opt_present("extern-html-root-takes-precedence");
         let html_no_source = matches.opt_present("html-no-source");
@@ -801,6 +804,13 @@ impl Options {
             .with_note("`--generate-link-to-definition` option will be ignored")
             .emit();
         }
+        if generate_macro_expansion && (show_coverage || output_format != OutputFormat::Html) {
+            dcx.struct_warn(
+                "`--generate-macro-expansion` option can only be used with HTML output format",
+            )
+            .with_note("`--generate-macro-expansion` option will be ignored")
+            .emit();
+        }
 
         let scrape_examples_options = ScrapeExamplesOptions::new(matches, dcx);
         let with_examples = matches.opt_strs("with-examples");
@@ -881,6 +891,7 @@ impl Options {
             unstable_features,
             emit,
             generate_link_to_definition,
+            generate_macro_expansion,
             call_locations,
             no_emit_shared: false,
             html_no_source,
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 165b0c587b0..7e362791af9 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -281,7 +281,7 @@ fn get_expansion<'a, W: Write>(
         && let Some(expanded_code) = expanded_codes.iter().find(|code| code.start_line == line)
     {
         let (closing, reopening) = if let Some(current_class) = token_handler.current_class
-            && let class = current_class.as_html() 
+            && let class = current_class.as_html()
             && !class.is_empty()
         {
             ("</span>", format!("<span class=\"{class}\">"))
@@ -321,11 +321,15 @@ fn end_expansion<W: Write>(token_handler: &mut TokenHandler<'_, '_, W>, level: u
     }
     let mut out = String::new();
     let mut end = String::new();
-    for (tag, class) in token_handler.closing_tags.iter().skip(token_handler.closing_tags.len() - level) {
+    for (tag, class) in
+        token_handler.closing_tags.iter().skip(token_handler.closing_tags.len() - level)
+    {
         out.push_str(tag);
         end.push_str(&format!("<span class=\"{}\">", class.as_html()));
     }
-    token_handler.pending_elems.push((Cow::Owned(format!("</span></span>{out}{end}")), Some(Class::Expansion)));
+    token_handler
+        .pending_elems
+        .push((Cow::Owned(format!("</span></span>{out}{end}")), Some(Class::Expansion)));
 }
 
 #[derive(Clone, Copy)]
@@ -399,8 +403,7 @@ pub(super) fn write_code(
         .href_context
         .as_ref()
         .and_then(|c| c.context.shared.expanded_codes.get(&c.file_span.lo()));
-    let mut current_expansion =
-        get_expansion(&mut token_handler, expanded_codes, line);
+    let mut current_expansion = get_expansion(&mut token_handler, expanded_codes, line);
     token_handler.write_pending_elems(None);
     let mut level = 0;
 
@@ -440,8 +443,7 @@ pub(super) fn write_code(
                             .push((Cow::Borrowed(text), Some(Class::Backline(line))));
                     }
                     if current_expansion.is_none() {
-                        current_expansion =
-                            get_expansion(&mut token_handler, expanded_codes, line);
+                        current_expansion = get_expansion(&mut token_handler, expanded_codes, line);
                     }
                 } else {
                     token_handler.pending_elems.push((Cow::Borrowed(text), class));
@@ -887,7 +889,9 @@ impl<'src> Classifier<'src> {
     ) {
         let lookahead = self.peek();
         let file_span = self.file_span;
-        let no_highlight = |sink: &mut dyn FnMut(_, _)| sink(new_span(before, text, file_span), Highlight::Token { text, class: None });
+        let no_highlight = |sink: &mut dyn FnMut(_, _)| {
+            sink(new_span(before, text, file_span), Highlight::Token { text, class: None })
+        };
         let whitespace = |sink: &mut dyn FnMut(_, _)| {
             let mut start = 0u32;
             for part in text.split('\n').intersperse("\n").filter(|s| !s.is_empty()) {
@@ -1053,7 +1057,10 @@ impl<'src> Classifier<'src> {
             TokenKind::CloseBracket => {
                 if self.in_attribute {
                     self.in_attribute = false;
-                    sink(new_span(before, text, file_span), Highlight::Token { text: "]", class: None });
+                    sink(
+                        new_span(before, text, file_span),
+                        Highlight::Token { text: "]", class: None },
+                    );
                     sink(DUMMY_SP, Highlight::ExitSpan);
                     return;
                 }
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 33dec1c24e6..af9af5ba2b3 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -492,6 +492,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             generate_redirect_map,
             show_type_layout,
             generate_link_to_definition,
+            generate_macro_expansion,
             call_locations,
             no_emit_shared,
             html_no_source,
@@ -556,6 +557,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             &src_root,
             include_sources,
             generate_link_to_definition,
+            generate_macro_expansion,
         );
 
         let (sender, receiver) = channel();
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 842da838049..10969188dc7 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -60,6 +60,7 @@ pub(crate) fn collect_spans_and_sources(
     src_root: &Path,
     include_sources: bool,
     generate_link_to_definition: bool,
+    generate_macro_expansion: bool,
 ) -> (
     FxIndexMap<PathBuf, String>,
     FxHashMap<Span, LinkFromSrc>,
@@ -69,7 +70,9 @@ pub(crate) fn collect_spans_and_sources(
         let mut visitor = SpanMapVisitor { tcx, matches: FxHashMap::default() };
         let mut expanded_visitor = ExpandedCodeVisitor { tcx, expanded_codes: Vec::new() };
 
-        tcx.hir_walk_toplevel_module(&mut expanded_visitor);
+        if generate_macro_expansion {
+            tcx.hir_walk_toplevel_module(&mut expanded_visitor);
+        }
         if generate_link_to_definition {
             tcx.hir_walk_toplevel_module(&mut visitor);
         }
@@ -350,10 +353,7 @@ impl<'tcx> ExpandedCodeVisitor<'tcx> {
             }
         } else {
             // We add a new item.
-            self.expanded_codes.push(ExpandedCodeInfo {
-                span: new_span,
-                code: f(self.tcx),
-            });
+            self.expanded_codes.push(ExpandedCodeInfo { span: new_span, code: f(self.tcx) });
         }
     }
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 28dbd8ba7d3..09e7a42e944 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -704,6 +704,14 @@ fn opts() -> Vec<RustcOptGroup> {
             "removed, see issue #44136 <https://github.com/rust-lang/rust/issues/44136> for more information",
             "[rust]",
         ),
+        opt(
+            Unstable,
+            Flag,
+            "",
+            "generate-macro-expansion",
+            "Add possibility to expand macros in the HTML source code pages",
+            "",
+        ),
     ]
 }