Skip to content

Commit 3a24abd

Browse files
committed
Auto merge of #86841 - GuillaumeGomez:reexported-macro-2-render, r=Stupremee
Fix rendering of reexported macros 2.0 and fix visibility of reexported items So, this PR grew a bit out of focus, it does the following things: * Fixes #86276. * Fixes visibility display for reexported items: it now takes the visibility of the "use" statement rather than the visibility of the reexported item itself). * Fixes the display of reexported items if "--document-private-items" option is used. Before, they were simply skipped. * Fixes inconsistency on typedef items: they didn't display their visibility contrary to other items. I added tests to check everything listed above. cc `@camelid` `@ollie27` (in case one of you want to review?) r? `@jyn514`
2 parents e97c29b + 74d71c2 commit 3a24abd

File tree

7 files changed

+232
-56
lines changed

7 files changed

+232
-56
lines changed

src/librustdoc/clean/inline.rs

+32-25
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>;
4141
crate fn try_inline(
4242
cx: &mut DocContext<'_>,
4343
parent_module: DefId,
44+
import_def_id: Option<DefId>,
4445
res: Res,
4546
name: Symbol,
4647
attrs: Option<Attrs<'_>>,
@@ -108,7 +109,7 @@ crate fn try_inline(
108109
clean::ConstantItem(build_const(cx, did))
109110
}
110111
Res::Def(DefKind::Macro(kind), did) => {
111-
let mac = build_macro(cx, did, name);
112+
let mac = build_macro(cx, did, name, import_def_id);
112113

113114
let type_kind = match kind {
114115
MacroKind::Bang => ItemType::Macro,
@@ -123,14 +124,13 @@ crate fn try_inline(
123124

124125
let (attrs, cfg) = merge_attrs(cx, Some(parent_module), load_attrs(cx, did), attrs_clone);
125126
cx.inlined.insert(did.into());
126-
ret.push(clean::Item::from_def_id_and_attrs_and_parts(
127-
did,
128-
Some(name),
129-
kind,
130-
box attrs,
131-
cx,
132-
cfg,
133-
));
127+
let mut item =
128+
clean::Item::from_def_id_and_attrs_and_parts(did, Some(name), kind, box attrs, cx, cfg);
129+
if let Some(import_def_id) = import_def_id {
130+
// The visibility needs to reflect the one from the reexport and not from the "source" DefId.
131+
item.visibility = cx.tcx.visibility(import_def_id).clean(cx);
132+
}
133+
ret.push(item);
134134
Some(ret)
135135
}
136136

@@ -509,7 +509,9 @@ fn build_module(
509509
)),
510510
cfg: None,
511511
});
512-
} else if let Some(i) = try_inline(cx, did, item.res, item.ident.name, None, visited) {
512+
} else if let Some(i) =
513+
try_inline(cx, did, None, item.res, item.ident.name, None, visited)
514+
{
513515
items.extend(i)
514516
}
515517
}
@@ -543,21 +545,26 @@ fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::St
543545
}
544546
}
545547

546-
fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind {
547-
let imported_from = cx.tcx.crate_name(did.krate);
548-
match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
549-
LoadedMacro::MacroDef(def, _) => {
550-
if let ast::ItemKind::MacroDef(ref def) = def.kind {
551-
let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
552-
let matchers = tts.chunks(4).map(|arm| &arm[0]);
553-
554-
let source = format!(
555-
"macro_rules! {} {{\n{}}}",
556-
name,
557-
utils::render_macro_arms(matchers, ";")
558-
);
559-
560-
clean::MacroItem(clean::Macro { source, imported_from: Some(imported_from) })
548+
fn build_macro(
549+
cx: &mut DocContext<'_>,
550+
def_id: DefId,
551+
name: Symbol,
552+
import_def_id: Option<DefId>,
553+
) -> clean::ItemKind {
554+
let imported_from = cx.tcx.crate_name(def_id.krate);
555+
match cx.enter_resolver(|r| r.cstore().load_macro_untracked(def_id, cx.sess())) {
556+
LoadedMacro::MacroDef(item_def, _) => {
557+
if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
558+
clean::MacroItem(clean::Macro {
559+
source: utils::display_macro_source(
560+
cx,
561+
name,
562+
def,
563+
def_id,
564+
cx.tcx.visibility(import_def_id.unwrap_or(def_id)),
565+
),
566+
imported_from: Some(imported_from),
567+
})
561568
} else {
562569
unreachable!()
563570
}

src/librustdoc/clean/mod.rs

+11-29
Original file line numberDiff line numberDiff line change
@@ -1997,6 +1997,7 @@ fn clean_extern_crate(
19971997
if let Some(items) = inline::try_inline(
19981998
cx,
19991999
cx.tcx.parent_module(krate.hir_id()).to_def_id(),
2000+
Some(krate.def_id.to_def_id()),
20002001
res,
20012002
name,
20022003
Some(attrs),
@@ -2052,7 +2053,8 @@ fn clean_use_statement(
20522053
// forcefully don't inline if this is not public or if the
20532054
// #[doc(no_inline)] attribute is present.
20542055
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
2055-
let mut denied = !import.vis.node.is_pub()
2056+
let mut denied = !(import.vis.node.is_pub()
2057+
|| (cx.render_options.document_private && import.vis.node.is_pub_restricted()))
20562058
|| pub_underscore
20572059
|| attrs.iter().any(|a| {
20582060
a.has_name(sym::doc)
@@ -2088,17 +2090,19 @@ fn clean_use_statement(
20882090
}
20892091
if !denied {
20902092
let mut visited = FxHashSet::default();
2093+
let import_def_id = import.def_id.to_def_id();
20912094

20922095
if let Some(mut items) = inline::try_inline(
20932096
cx,
20942097
cx.tcx.parent_module(import.hir_id()).to_def_id(),
2098+
Some(import_def_id),
20952099
path.res,
20962100
name,
20972101
Some(attrs),
20982102
&mut visited,
20992103
) {
21002104
items.push(Item::from_def_id_and_parts(
2101-
import.def_id.to_def_id(),
2105+
import_def_id,
21022106
None,
21032107
ImportItem(Import::new_simple(name, resolve_use_source(cx, path), false)),
21042108
cx,
@@ -2157,37 +2161,15 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
21572161
fn clean(&self, cx: &mut DocContext<'_>) -> Item {
21582162
let (item, renamed) = self;
21592163
let name = renamed.unwrap_or(item.ident.name);
2160-
let tts = item.ast.body.inner_tokens().trees().collect::<Vec<_>>();
2161-
// Extract the macro's matchers. They represent the "interface" of the macro.
2162-
let matchers = tts.chunks(4).map(|arm| &arm[0]);
2163-
2164-
let source = if item.ast.macro_rules {
2165-
format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
2166-
} else {
2167-
let vis = item.vis.clean(cx);
2168-
let def_id = item.def_id.to_def_id();
2169-
2170-
if matchers.len() <= 1 {
2171-
format!(
2172-
"{}macro {}{} {{\n ...\n}}",
2173-
vis.to_src_with_space(cx.tcx, def_id),
2174-
name,
2175-
matchers.map(render_macro_matcher).collect::<String>(),
2176-
)
2177-
} else {
2178-
format!(
2179-
"{}macro {} {{\n{}}}",
2180-
vis.to_src_with_space(cx.tcx, def_id),
2181-
name,
2182-
render_macro_arms(matchers, ","),
2183-
)
2184-
}
2185-
};
2164+
let def_id = item.def_id.to_def_id();
21862165

21872166
Item::from_hir_id_and_parts(
21882167
item.hir_id(),
21892168
Some(name),
2190-
MacroItem(Macro { source, imported_from: None }),
2169+
MacroItem(Macro {
2170+
source: display_macro_source(cx, name, &item.ast, def_id, &item.vis),
2171+
imported_from: None,
2172+
}),
21912173
cx,
21922174
)
21932175
}

src/librustdoc/clean/utils.rs

+36
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ use crate::clean::blanket_impl::BlanketImplFinder;
33
use crate::clean::{
44
inline, Clean, Crate, Generic, GenericArg, GenericArgs, ImportSource, Item, ItemKind, Lifetime,
55
Path, PathSegment, PolyTrait, Primitive, PrimitiveType, ResolvedPath, Type, TypeBinding,
6+
Visibility,
67
};
78
use crate::core::DocContext;
89
use crate::formats::item_type::ItemType;
910

11+
use rustc_ast as ast;
1012
use rustc_ast::tokenstream::TokenTree;
1113
use rustc_hir as hir;
1214
use rustc_hir::def::{DefKind, Res};
@@ -577,3 +579,37 @@ pub(super) fn render_macro_arms<'a>(
577579
pub(super) fn render_macro_matcher(matcher: &TokenTree) -> String {
578580
rustc_ast_pretty::pprust::tt_to_string(matcher)
579581
}
582+
583+
pub(super) fn display_macro_source(
584+
cx: &mut DocContext<'_>,
585+
name: Symbol,
586+
def: &ast::MacroDef,
587+
def_id: DefId,
588+
vis: impl Clean<Visibility>,
589+
) -> String {
590+
let tts: Vec<_> = def.body.inner_tokens().into_trees().collect();
591+
// Extract the spans of all matchers. They represent the "interface" of the macro.
592+
let matchers = tts.chunks(4).map(|arm| &arm[0]);
593+
594+
if def.macro_rules {
595+
format!("macro_rules! {} {{\n{}}}", name, render_macro_arms(matchers, ";"))
596+
} else {
597+
let vis = vis.clean(cx);
598+
599+
if matchers.len() <= 1 {
600+
format!(
601+
"{}macro {}{} {{\n ...\n}}",
602+
vis.to_src_with_space(cx.tcx, def_id),
603+
name,
604+
matchers.map(render_macro_matcher).collect::<String>(),
605+
)
606+
} else {
607+
format!(
608+
"{}macro {} {{\n{}}}",
609+
vis.to_src_with_space(cx.tcx, def_id),
610+
name,
611+
render_macro_arms(matchers, ","),
612+
)
613+
}
614+
}
615+
}

src/librustdoc/html/render/print_item.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
133133
clean::StructItem(ref s) => item_struct(buf, cx, item, s),
134134
clean::UnionItem(ref s) => item_union(buf, cx, item, s),
135135
clean::EnumItem(ref e) => item_enum(buf, cx, item, e),
136-
clean::TypedefItem(ref t, _) => item_typedef(buf, cx, item, t),
136+
clean::TypedefItem(ref t, is_associated) => item_typedef(buf, cx, item, t, is_associated),
137137
clean::MacroItem(ref m) => item_macro(buf, cx, item, m),
138138
clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m),
139139
clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
@@ -837,9 +837,18 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean:
837837
render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All)
838838
}
839839

840-
fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
840+
fn item_typedef(
841+
w: &mut Buffer,
842+
cx: &Context<'_>,
843+
it: &clean::Item,
844+
t: &clean::Typedef,
845+
is_associated: bool,
846+
) {
841847
w.write_str("<pre class=\"rust typedef\">");
842848
render_attributes_in_pre(w, it, "");
849+
if !is_associated {
850+
write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
851+
}
843852
write!(
844853
w,
845854
"type {}{}{where_clause} = {type_};</pre>",
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#![feature(decl_macro)]
2+
3+
pub macro addr_of($place:expr) {
4+
&raw const $place
5+
}
6+
7+
pub macro addr_of_self($place:expr) {
8+
&raw const $place
9+
}
10+
11+
pub macro addr_of_crate($place:expr) {
12+
&raw const $place
13+
}
14+
15+
pub struct Foo;
16+
pub struct FooSelf;
17+
pub struct FooCrate;
18+
19+
pub enum Bar { Foo, }
20+
pub enum BarSelf { Foo, }
21+
pub enum BarCrate { Foo, }
22+
23+
pub fn foo() {}
24+
pub fn foo_self() {}
25+
pub fn foo_crate() {}
26+
27+
pub type Type = i32;
28+
pub type TypeSelf = i32;
29+
pub type TypeCrate = i32;
30+
31+
pub union Union {
32+
a: i8,
33+
b: i8,
34+
}
35+
pub union UnionSelf {
36+
a: i8,
37+
b: i8,
38+
}
39+
pub union UnionCrate {
40+
a: i8,
41+
b: i8,
42+
}

src/test/rustdoc/reexports-priv.rs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// aux-build: reexports.rs
2+
// compile-flags: --document-private-items
3+
4+
#![crate_name = "foo"]
5+
6+
extern crate reexports;
7+
8+
// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
9+
pub use reexports::addr_of;
10+
// @has 'foo/macro.addr_of_crate.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_crate($place : expr) {'
11+
pub(crate) use reexports::addr_of_crate;
12+
// @has 'foo/macro.addr_of_self.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_self($place : expr) {'
13+
pub(self) use reexports::addr_of_self;
14+
15+
// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
16+
pub use reexports::Foo;
17+
// @has 'foo/struct.FooCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooCrate;'
18+
pub(crate) use reexports::FooCrate;
19+
// @has 'foo/struct.FooSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooSelf;'
20+
pub(self) use reexports::FooSelf;
21+
22+
// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
23+
pub use reexports::Bar;
24+
// @has 'foo/enum.BarCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarCrate {'
25+
pub(crate) use reexports::BarCrate;
26+
// @has 'foo/enum.BarSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarSelf {'
27+
pub(self) use reexports::BarSelf;
28+
29+
// @has 'foo/fn.foo.html' '//*[@class="rust fn"]' 'pub fn foo()'
30+
pub use reexports::foo;
31+
// @has 'foo/fn.foo_crate.html' '//*[@class="rust fn"]' 'pub(crate) fn foo_crate()'
32+
pub(crate) use reexports::foo_crate;
33+
// @has 'foo/fn.foo_self.html' '//*[@class="rust fn"]' 'pub(crate) fn foo_self()'
34+
pub(self) use reexports::foo_self;
35+
36+
// @has 'foo/type.Type.html' '//*[@class="rust typedef"]' 'pub type Type ='
37+
pub use reexports::Type;
38+
// @has 'foo/type.TypeCrate.html' '//*[@class="rust typedef"]' 'pub(crate) type TypeCrate ='
39+
pub(crate) use reexports::TypeCrate;
40+
// @has 'foo/type.TypeSelf.html' '//*[@class="rust typedef"]' 'pub(crate) type TypeSelf ='
41+
pub(self) use reexports::TypeSelf;
42+
43+
// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
44+
pub use reexports::Union;
45+
// @has 'foo/union.UnionCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionCrate {'
46+
pub(crate) use reexports::UnionCrate;
47+
// @has 'foo/union.UnionSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionSelf {'
48+
pub(self) use reexports::UnionSelf;
49+
50+
pub mod foo {
51+
// @!has 'foo/foo/union.Union.html'
52+
use crate::reexports::Union;
53+
}

src/test/rustdoc/reexports.rs

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// aux-build: reexports.rs
2+
3+
#![crate_name = "foo"]
4+
5+
extern crate reexports;
6+
7+
// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
8+
pub use reexports::addr_of;
9+
// @!has 'foo/macro.addr_of_crate.html'
10+
pub(crate) use reexports::addr_of_crate;
11+
// @!has 'foo/macro.addr_of_self.html'
12+
pub(self) use reexports::addr_of_self;
13+
14+
// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
15+
pub use reexports::Foo;
16+
// @!has 'foo/struct.FooCrate.html'
17+
pub(crate) use reexports::FooCrate;
18+
// @!has 'foo/struct.FooSelf.html'
19+
pub(self) use reexports::FooSelf;
20+
21+
// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
22+
pub use reexports::Bar;
23+
// @!has 'foo/enum.BarCrate.html'
24+
pub(crate) use reexports::BarCrate;
25+
// @!has 'foo/enum.BarSelf.html'
26+
pub(self) use reexports::BarSelf;
27+
28+
// @has 'foo/fn.foo.html' '//*[@class="rust fn"]' 'pub fn foo()'
29+
pub use reexports::foo;
30+
// @!has 'foo/fn.foo_crate.html'
31+
pub(crate) use reexports::foo_crate;
32+
// @!has 'foo/fn.foo_self.html'
33+
pub(self) use reexports::foo_self;
34+
35+
// @has 'foo/type.Type.html' '//*[@class="rust typedef"]' 'pub type Type ='
36+
pub use reexports::Type;
37+
// @!has 'foo/type.TypeCrate.html'
38+
pub(crate) use reexports::TypeCrate;
39+
// @!has 'foo/type.TypeSelf.html'
40+
pub(self) use reexports::TypeSelf;
41+
42+
// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
43+
pub use reexports::Union;
44+
// @!has 'foo/union.UnionCrate.html'
45+
pub(crate) use reexports::UnionCrate;
46+
// @!has 'foo/union.UnionSelf.html'
47+
pub(self) use reexports::UnionSelf;

0 commit comments

Comments
 (0)