diff options
| author | bors <bors@rust-lang.org> | 2021-07-05 05:09:35 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-07-05 05:09:35 +0000 |
| commit | 09d9b608d647fdc19a933c661f943a010c8d84a5 (patch) | |
| tree | 7359a589e6c9ddae2b858fb1ef13b9c5ede1f697 /src/librustdoc | |
| parent | 44860d13fa866d002a5f29a4684dad29ff268af9 (diff) | |
| parent | 7ffec7028a54aeed6076f7043734b682fdf68f6e (diff) | |
Auto merge of #86282 - camelid:macro_rules-matchers, r=jyn514
Pretty-print macro matchers instead of using source code Fixes #86208.
Diffstat (limited to 'src/librustdoc')
| -rw-r--r-- | src/librustdoc/clean/inline.rs | 28 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 21 | ||||
| -rw-r--r-- | src/librustdoc/clean/utils.rs | 37 |
3 files changed, 39 insertions, 47 deletions
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 829b54f1fc1..7b1b23ff8e6 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -13,10 +13,9 @@ use rustc_metadata::creader::LoadedMacro; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Symbol}; -use rustc_span::Span; use crate::clean::{ - self, Attributes, AttributesExt, FakeDefId, GetDefId, NestedAttributesExt, ToSource, Type, + self, utils, Attributes, AttributesExt, FakeDefId, GetDefId, NestedAttributesExt, Type, }; use crate::core::DocContext; use crate::formats::item_type::ItemType; @@ -547,23 +546,20 @@ fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::Item let imported_from = cx.tcx.crate_name(did.krate); match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) { LoadedMacro::MacroDef(def, _) => { - let matchers: Vec<Span> = if let ast::ItemKind::MacroDef(ref def) = def.kind { + if let ast::ItemKind::MacroDef(ref def) = def.kind { let tts: Vec<_> = def.body.inner_tokens().into_trees().collect(); - tts.chunks(4).map(|arm| arm[0].span()).collect() - } else { - unreachable!() - }; + let matchers = tts.chunks(4).map(|arm| &arm[0]); - let source = format!( - "macro_rules! {} {{\n{}}}", - name.clean(cx), - matchers - .iter() - .map(|span| { format!(" {} => {{ ... }};\n", span.to_src(cx)) }) - .collect::<String>() - ); + let source = format!( + "macro_rules! {} {{\n{}}}", + name.clean(cx), + utils::render_macro_arms(matchers, ";") + ); - clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) }) + clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) }) + } else { + unreachable!() + } } LoadedMacro::ProcMacro(ext) => clean::ProcMacroItem(clean::ProcMacro { kind: ext.macro_kind(), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 6abe1c7cd61..b0e75493aa4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2172,17 +2172,11 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) { let (item, renamed) = self; let name = renamed.unwrap_or(item.ident.name); let tts = item.ast.body.inner_tokens().trees().collect::<Vec<_>>(); - // Extract the spans of all matchers. They represent the "interface" of the macro. - let matchers = tts.chunks(4).map(|arm| arm[0].span()).collect::<Vec<_>>(); + // Extract the macro's matchers. They represent the "interface" of the macro. + let matchers = tts.chunks(4).map(|arm| &arm[0]); + let source = if item.ast.macro_rules { - format!( - "macro_rules! {} {{\n{}}}", - name, - matchers - .iter() - .map(|span| { format!(" {} => {{ ... }};\n", span.to_src(cx)) }) - .collect::<String>(), - ) + format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";")) } else { let vis = item.vis.clean(cx); let def_id = item.def_id.to_def_id(); @@ -2192,17 +2186,14 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) { "{}macro {}{} {{\n ...\n}}", vis.to_src_with_space(cx.tcx, def_id), name, - matchers.iter().map(|span| span.to_src(cx)).collect::<String>(), + matchers.map(render_macro_matcher).collect::<String>(), ) } else { format!( "{}macro {} {{\n{}}}", vis.to_src_with_space(cx.tcx, def_id), name, - matchers - .iter() - .map(|span| { format!(" {} => {{ ... }},\n", span.to_src(cx)) }) - .collect::<String>(), + render_macro_arms(matchers, ","), ) } }; diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index f70ccdd63f9..fb46b81102c 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -7,6 +7,7 @@ use crate::clean::{ use crate::core::DocContext; use crate::formats::item_type::ItemType; +use rustc_ast::tokenstream::TokenTree; use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; @@ -14,6 +15,7 @@ use rustc_middle::mir::interpret::ConstValue; use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; +use std::fmt::Write as _; use std::mem; #[cfg(test)] @@ -248,22 +250,6 @@ crate fn build_deref_target_impls(cx: &mut DocContext<'_>, items: &[Item], ret: } } -crate trait ToSource { - fn to_src(&self, cx: &DocContext<'_>) -> String; -} - -impl ToSource for rustc_span::Span { - fn to_src(&self, cx: &DocContext<'_>) -> String { - debug!("converting span {:?} to snippet", self); - let sn = match cx.sess().source_map().span_to_snippet(*self) { - Ok(x) => x, - Err(_) => String::new(), - }; - debug!("got snippet {}", sn); - sn - } -} - crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { use rustc_hir::*; debug!("trying to get a name from pattern: {:?}", p); @@ -572,3 +558,22 @@ crate fn has_doc_flag(attrs: ty::Attributes<'_>, flag: Symbol) -> bool { /// /// Set by `bootstrap::Builder::doc_rust_lang_org_channel` in order to keep tests passing on beta/stable. crate const DOC_RUST_LANG_ORG_CHANNEL: &'static str = env!("DOC_RUST_LANG_ORG_CHANNEL"); + +/// Render a sequence of macro arms in a format suitable for displaying to the user +/// as part of an item declaration. +pub(super) fn render_macro_arms<'a>( + matchers: impl Iterator<Item = &'a TokenTree>, + arm_delim: &str, +) -> String { + let mut out = String::new(); + for matcher in matchers { + writeln!(out, " {} => {{ ... }}{}", render_macro_matcher(matcher), arm_delim).unwrap(); + } + out +} + +/// Render a macro matcher in a format suitable for displaying to the user +/// as part of an item declaration. +pub(super) fn render_macro_matcher(matcher: &TokenTree) -> String { + rustc_ast_pretty::pprust::tt_to_string(matcher) +} |
