mirror of https://github.com/rust-lang/rust.git
rustdoc: clean up and test macro visibility print
This fixes the overly-complex invariant mentioned in <https://github.com/rust-lang/rust/pull/83237#issuecomment-815346570>, where the macro source can't have any links in it only because the cache hasn't been populated yet.
This commit is contained in:
parent
72c63de2cc
commit
2dfd0bfe10
|
@ -2287,14 +2287,14 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
|
||||||
if matchers.len() <= 1 {
|
if matchers.len() <= 1 {
|
||||||
format!(
|
format!(
|
||||||
"{}macro {}{} {{\n ...\n}}",
|
"{}macro {}{} {{\n ...\n}}",
|
||||||
vis.print_with_space(cx.tcx, def_id, &cx.cache),
|
vis.to_src_with_space(cx.tcx, def_id),
|
||||||
name,
|
name,
|
||||||
matchers.iter().map(|span| span.to_src(cx)).collect::<String>(),
|
matchers.iter().map(|span| span.to_src(cx)).collect::<String>(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"{}macro {} {{\n{}}}",
|
"{}macro {} {{\n{}}}",
|
||||||
vis.print_with_space(cx.tcx, def_id, &cx.cache),
|
vis.to_src_with_space(cx.tcx, def_id),
|
||||||
name,
|
name,
|
||||||
matchers
|
matchers
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -1186,8 +1186,6 @@ impl clean::Visibility {
|
||||||
item_did: DefId,
|
item_did: DefId,
|
||||||
cache: &'a Cache,
|
cache: &'a Cache,
|
||||||
) -> impl fmt::Display + 'a + Captures<'tcx> {
|
) -> impl fmt::Display + 'a + Captures<'tcx> {
|
||||||
use rustc_span::symbol::kw;
|
|
||||||
|
|
||||||
let to_print = match self {
|
let to_print = match self {
|
||||||
clean::Public => "pub ".to_owned(),
|
clean::Public => "pub ".to_owned(),
|
||||||
clean::Inherited => String::new(),
|
clean::Inherited => String::new(),
|
||||||
|
@ -1212,18 +1210,11 @@ impl clean::Visibility {
|
||||||
} else {
|
} else {
|
||||||
let path = tcx.def_path(vis_did);
|
let path = tcx.def_path(vis_did);
|
||||||
debug!("path={:?}", path);
|
debug!("path={:?}", path);
|
||||||
let first_name =
|
|
||||||
path.data[0].data.get_opt_name().expect("modules are always named");
|
|
||||||
// modified from `resolved_path()` to work with `DefPathData`
|
// modified from `resolved_path()` to work with `DefPathData`
|
||||||
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
|
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
|
||||||
let anchor = anchor(vis_did, &last_name.as_str(), cache).to_string();
|
let anchor = anchor(vis_did, &last_name.as_str(), cache).to_string();
|
||||||
|
|
||||||
let mut s = "pub(".to_owned();
|
let mut s = "pub(in ".to_owned();
|
||||||
if path.data.len() != 1
|
|
||||||
|| (first_name != kw::SelfLower && first_name != kw::Super)
|
|
||||||
{
|
|
||||||
s.push_str("in ");
|
|
||||||
}
|
|
||||||
for seg in &path.data[..path.data.len() - 1] {
|
for seg in &path.data[..path.data.len() - 1] {
|
||||||
s.push_str(&format!("{}::", seg.data.get_opt_name().unwrap()));
|
s.push_str(&format!("{}::", seg.data.get_opt_name().unwrap()));
|
||||||
}
|
}
|
||||||
|
@ -1234,6 +1225,43 @@ impl clean::Visibility {
|
||||||
};
|
};
|
||||||
display_fn(move |f| f.write_str(&to_print))
|
display_fn(move |f| f.write_str(&to_print))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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.
|
||||||
|
crate fn to_src_with_space<'a, 'tcx: 'a>(
|
||||||
|
self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
item_did: DefId,
|
||||||
|
) -> impl fmt::Display + 'a + Captures<'tcx> {
|
||||||
|
let to_print = match self {
|
||||||
|
clean::Public => "pub ".to_owned(),
|
||||||
|
clean::Inherited => String::new(),
|
||||||
|
clean::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.index == CRATE_DEF_INDEX {
|
||||||
|
"pub(crate) ".to_owned()
|
||||||
|
} else if parent_module == Some(vis_did) {
|
||||||
|
// `pub(in foo)` where `foo` is the parent module
|
||||||
|
// is the same as no visibility modifier
|
||||||
|
String::new()
|
||||||
|
} else if parent_module
|
||||||
|
.map(|parent| find_nearest_parent_module(tcx, parent))
|
||||||
|
.flatten()
|
||||||
|
== Some(vis_did)
|
||||||
|
{
|
||||||
|
"pub(super) ".to_owned()
|
||||||
|
} else {
|
||||||
|
format!("pub(in {}) ", tcx.def_path_str(vis_did))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
display_fn(move |f| f.write_str(&to_print))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crate trait PrintWithSpace {
|
crate trait PrintWithSpace {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// compile-flags: --document-private-items
|
||||||
|
|
||||||
#![feature(decl_macro)]
|
#![feature(decl_macro)]
|
||||||
|
|
||||||
// @has decl_macro/macro.my_macro.html //pre 'pub macro my_macro() {'
|
// @has decl_macro/macro.my_macro.html //pre 'pub macro my_macro() {'
|
||||||
|
@ -37,3 +39,18 @@ pub macro my_macro_multi {
|
||||||
pub macro by_example_single {
|
pub macro by_example_single {
|
||||||
($foo:expr) => {}
|
($foo:expr) => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod a {
|
||||||
|
mod b {
|
||||||
|
// @has decl_macro/a/b/macro.by_example_vis.html //pre 'pub(super) macro by_example_vis($foo:expr) {'
|
||||||
|
pub(in super) macro by_example_vis {
|
||||||
|
($foo:expr) => {}
|
||||||
|
}
|
||||||
|
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) {'
|
||||||
|
pub(in a) macro by_example_vis_named {
|
||||||
|
($foo:expr) => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue