Skip to content

Commit

Permalink
rustdoc: Treat decl macros like other items when it comes to visibility
Browse files Browse the repository at this point in the history
  • Loading branch information
fmease committed Oct 29, 2024
1 parent 3f1be1e commit 179cba4
Show file tree
Hide file tree
Showing 8 changed files with 22 additions and 80 deletions.
18 changes: 5 additions & 13 deletions src/librustdoc/clean/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,7 @@ pub(crate) fn try_inline(
})
}
Res::Def(DefKind::Macro(kind), did) => {
let is_doc_hidden = cx.tcx.is_doc_hidden(did)
|| attrs_without_docs
.map(|(attrs, _)| attrs)
.is_some_and(|attrs| utils::attrs_have_doc_flag(attrs.iter(), sym::hidden));
let mac = build_macro(cx, did, name, import_def_id, kind, is_doc_hidden);
let mac = build_macro(cx, did, name, kind);

let type_kind = match kind {
MacroKind::Bang => ItemType::Macro,
Expand Down Expand Up @@ -740,18 +736,14 @@ fn build_macro(
cx: &mut DocContext<'_>,
def_id: DefId,
name: Symbol,
import_def_id: Option<LocalDefId>,
macro_kind: MacroKind,
is_doc_hidden: bool,
) -> clean::ItemKind {
match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.tcx) {
LoadedMacro::MacroDef { def, .. } => match macro_kind {
MacroKind::Bang => {
let vis = cx.tcx.visibility(import_def_id.map(|d| d.to_def_id()).unwrap_or(def_id));
clean::MacroItem(clean::Macro {
source: utils::display_macro_source(cx, name, &def, def_id, vis, is_doc_hidden),
})
}
MacroKind::Bang => clean::MacroItem(clean::Macro {
source: utils::display_macro_source(cx, name, &def),
macro_rules: def.macro_rules,
}),
MacroKind::Derive | MacroKind::Attr => {
clean::ProcMacroItem(clean::ProcMacro { kind: macro_kind, helpers: Vec::new() })
}
Expand Down
11 changes: 4 additions & 7 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2783,13 +2783,10 @@ fn clean_maybe_renamed_item<'tcx>(
fields: variant_data.fields().iter().map(|x| clean_field(x, cx)).collect(),
}),
ItemKind::Impl(impl_) => return clean_impl(impl_, item.owner_id.def_id, cx),
ItemKind::Macro(macro_def, MacroKind::Bang) => {
let ty_vis = cx.tcx.visibility(def_id);
MacroItem(Macro {
// FIXME this shouldn't be false
source: display_macro_source(cx, name, macro_def, def_id, ty_vis, false),
})
}
ItemKind::Macro(macro_def, MacroKind::Bang) => MacroItem(Macro {
source: display_macro_source(cx, name, macro_def),
macro_rules: macro_def.macro_rules,
}),
ItemKind::Macro(_, macro_kind) => clean_proc_macro(item, &mut name, macro_kind, cx),
// proc macros can have a name set by attributes
ItemKind::Fn(ref sig, generics, body_id) => {
Expand Down
2 changes: 2 additions & 0 deletions src/librustdoc/clean/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2544,6 +2544,8 @@ pub(crate) struct ImportSource {
#[derive(Clone, Debug)]
pub(crate) struct Macro {
pub(crate) source: String,
/// Whether the macro was defined via `macro_rules!` as opposed to `macro`.
pub(crate) macro_rules: bool,
}

#[derive(Clone, Debug)]
Expand Down
13 changes: 2 additions & 11 deletions src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ use crate::clean::{
clean_middle_ty, inline,
};
use crate::core::DocContext;
use crate::html::format::visibility_to_src_with_space;

#[cfg(test)]
mod tests;
Expand Down Expand Up @@ -620,9 +619,6 @@ pub(super) fn display_macro_source(
cx: &mut DocContext<'_>,
name: Symbol,
def: &ast::MacroDef,
def_id: DefId,
vis: ty::Visibility<DefId>,
is_doc_hidden: bool,
) -> String {
// Extract the spans of all matchers. They represent the "interface" of the macro.
let matchers = def.body.tokens.chunks(4).map(|arm| &arm[0]);
Expand All @@ -632,18 +628,13 @@ pub(super) fn display_macro_source(
} else {
if matchers.len() <= 1 {
format!(
"{vis}macro {name}{matchers} {{\n ...\n}}",
vis = visibility_to_src_with_space(Some(vis), cx.tcx, def_id, is_doc_hidden),
"macro {name}{matchers} {{\n ...\n}}",
matchers = matchers
.map(|matcher| render_macro_matcher(cx.tcx, matcher))
.collect::<String>(),
)
} else {
format!(
"{vis}macro {name} {{\n{arms}}}",
vis = visibility_to_src_with_space(Some(vis), cx.tcx, def_id, is_doc_hidden),
arms = render_macro_arms(cx.tcx, matchers, ","),
)
format!("macro {name} {{\n{arms}}}", arms = render_macro_arms(cx.tcx, matchers, ","))
}
}
}
Expand Down
41 changes: 0 additions & 41 deletions src/librustdoc/html/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1616,47 +1616,6 @@ pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
})
}

/// This function is the same as print_with_space, except that it renders no links.
/// It's used for macros' rendered source view, which is syntax highlighted and cannot have
/// any HTML in it.
pub(crate) fn visibility_to_src_with_space<'a, 'tcx: 'a>(
visibility: Option<ty::Visibility<DefId>>,
tcx: TyCtxt<'tcx>,
item_did: DefId,
is_doc_hidden: bool,
) -> impl Display + 'a + Captures<'tcx> {
let vis: Cow<'static, str> = match visibility {
None => "".into(),
Some(ty::Visibility::Public) => "pub ".into(),
Some(ty::Visibility::Restricted(vis_did)) => {
// FIXME(camelid): This may not work correctly if `item_did` is a module.
// However, rustdoc currently never displays a module's
// visibility, so it shouldn't matter.
let parent_module = find_nearest_parent_module(tcx, item_did);

if vis_did.is_crate_root() {
"pub(crate) ".into()
} else if parent_module == Some(vis_did) {
// `pub(in foo)` where `foo` is the parent module
// is the same as no visibility modifier
"".into()
} else if parent_module.and_then(|parent| find_nearest_parent_module(tcx, parent))
== Some(vis_did)
{
"pub(super) ".into()
} else {
format!("pub(in {}) ", tcx.def_path_str(vis_did)).into()
}
}
};
display_fn(move |f| {
if is_doc_hidden {
f.write_str("#[doc(hidden)] ")?;
}
f.write_str(&vis)
})
}

pub(crate) trait PrintWithSpace {
fn print_with_space(&self) -> &str;
}
Expand Down
7 changes: 0 additions & 7 deletions src/librustdoc/html/highlight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,6 @@ pub(crate) fn render_example_with_highlighting(
write_footer(out, playground_button);
}

/// Highlights `src` as an item-decl, returning the HTML output.
pub(crate) fn render_item_decl_with_highlighting(src: &str, out: &mut Buffer) {
write!(out, "<pre class=\"rust item-decl\">");
write_code(out, src, None, None);
write!(out, "</pre>");
}

fn write_header(
out: &mut Buffer,
class: &str,
Expand Down
8 changes: 7 additions & 1 deletion src/librustdoc/html/render/print_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1745,7 +1745,13 @@ fn item_variants(
}

fn item_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Macro) {
highlight::render_item_decl_with_highlighting(&t.source, w);
wrap_item(w, |w| {
// FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`.
if !t.macro_rules {
write!(w, "{}", visibility_print_with_space(it, cx));
}
highlight::write_code(w, &t.source, None, None);
});
write!(w, "{}", document(cx, it, None, HeadingOffset::H2))
}

Expand Down
2 changes: 2 additions & 0 deletions tests/rustdoc/decl_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ mod a {
}
mod c {
//@ has decl_macro/a/b/c/macro.by_example_vis_named.html //pre 'pub(in a) macro by_example_vis_named($foo:expr) {'
// Regression test for <https://github.com/rust-lang/rust/issues/83000>:
//@ has - '//pre[@class="rust item-decl"]//a[@class="mod"]/@href' '../../index.html'
pub(in a) macro by_example_vis_named {
($foo:expr) => {}
}
Expand Down

0 comments on commit 179cba4

Please sign in to comment.