Skip to content

Commit 50c1c27

Browse files
committed
Fix bugs; fix and add tests
1 parent d3f4c48 commit 50c1c27

File tree

8 files changed

+110
-87
lines changed

8 files changed

+110
-87
lines changed

src/librustdoc/clean/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -2299,14 +2299,20 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
22992299
if matchers.len() <= 1 {
23002300
format!(
23012301
"{}macro {}{} {{\n ...\n}}",
2302-
vis.print_with_space(cx.tcx, item.hir_id.owner),
2302+
vis.print_with_space(
2303+
cx.tcx,
2304+
cx.tcx.hir().local_def_id(item.hir_id).to_def_id()
2305+
),
23032306
name,
23042307
matchers.iter().map(|span| span.to_src(cx)).collect::<String>(),
23052308
)
23062309
} else {
23072310
format!(
23082311
"{}macro {} {{\n{}}}",
2309-
vis.print_with_space(cx.tcx, item.hir_id.owner),
2312+
vis.print_with_space(
2313+
cx.tcx,
2314+
cx.tcx.hir().local_def_id(item.hir_id).to_def_id()
2315+
),
23102316
name,
23112317
matchers
23122318
.iter()

src/librustdoc/clean/utils.rs

+23-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_hir::def::{DefKind, Res};
1515
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1616
use rustc_middle::mir::interpret::ConstValue;
1717
use rustc_middle::ty::subst::{GenericArgKind, SubstsRef};
18-
use rustc_middle::ty::{self, DefIdTree, Ty};
18+
use rustc_middle::ty::{self, DefIdTree, Ty, TyCtxt};
1919
use rustc_span::symbol::{kw, sym, Symbol};
2020
use std::mem;
2121

@@ -624,3 +624,25 @@ where
624624
*cx.impl_trait_bounds.borrow_mut() = old_bounds;
625625
r
626626
}
627+
628+
crate fn find_closest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option<DefId> {
629+
let mut current = def_id;
630+
// The immediate parent might not always be a module.
631+
// Find the first parent which is.
632+
loop {
633+
if let Some(parent) = tcx.parent(current) {
634+
if tcx.def_kind(parent) == DefKind::Mod {
635+
break Some(parent);
636+
}
637+
current = parent;
638+
} else {
639+
debug!(
640+
"{:?} has no parent (kind={:?}, original was {:?})",
641+
current,
642+
tcx.def_kind(current),
643+
def_id
644+
);
645+
break None;
646+
}
647+
}
648+
}

src/librustdoc/html/format.rs

+29-27
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ use std::fmt;
1212
use rustc_data_structures::fx::FxHashSet;
1313
use rustc_hir as hir;
1414
use rustc_middle::ty::TyCtxt;
15-
use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_INDEX};
15+
use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
1616
use rustc_target::spec::abi::Abi;
1717

18-
use crate::clean::{self, PrimitiveType};
18+
use crate::clean::{self, utils::find_closest_parent_module, PrimitiveType};
1919
use crate::formats::cache::cache;
2020
use crate::formats::item_type::ItemType;
2121
use crate::html::escape::Escape;
@@ -1088,38 +1088,40 @@ impl clean::Visibility {
10881088
crate fn print_with_space<'tcx>(
10891089
self,
10901090
tcx: TyCtxt<'tcx>,
1091-
item_did: LocalDefId,
1091+
item_did: DefId,
10921092
) -> impl fmt::Display + 'tcx {
10931093
use rustc_span::symbol::kw;
10941094

10951095
display_fn(move |f| match self {
10961096
clean::Public => f.write_str("pub "),
10971097
clean::Inherited => Ok(()),
1098-
clean::Visibility::Restricted(did)
1099-
if did.index == tcx.parent_module_from_def_id(item_did).local_def_index =>
1100-
{
1101-
Ok(())
1102-
}
1103-
clean::Visibility::Restricted(did) if did.index == CRATE_DEF_INDEX => {
1104-
write!(f, "pub(crate) ")
1105-
}
1106-
clean::Visibility::Restricted(did) => {
1107-
f.write_str("pub(")?;
1108-
let path = tcx.def_path(did);
1109-
debug!("path={:?}", path);
1110-
let first_name =
1111-
path.data[0].data.get_opt_name().expect("modules are always named");
1112-
if path.data.len() != 1 || (first_name != kw::SelfLower && first_name != kw::Super)
1113-
{
1114-
f.write_str("in ")?;
1115-
}
1116-
// modified from `resolved_path()` to work with `DefPathData`
1117-
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
1118-
for seg in &path.data[..path.data.len() - 1] {
1119-
write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
1098+
1099+
clean::Visibility::Restricted(vis_did) => {
1100+
if find_closest_parent_module(tcx, item_did) == Some(vis_did) {
1101+
// `pub(in foo)` where `foo` is the parent module
1102+
// is the same as no visibility modifier
1103+
Ok(())
1104+
} else if vis_did.index == CRATE_DEF_INDEX {
1105+
write!(f, "pub(crate) ")
1106+
} else {
1107+
f.write_str("pub(")?;
1108+
let path = tcx.def_path(vis_did);
1109+
debug!("path={:?}", path);
1110+
let first_name =
1111+
path.data[0].data.get_opt_name().expect("modules are always named");
1112+
if path.data.len() != 1
1113+
|| (first_name != kw::SelfLower && first_name != kw::Super)
1114+
{
1115+
f.write_str("in ")?;
1116+
}
1117+
// modified from `resolved_path()` to work with `DefPathData`
1118+
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
1119+
for seg in &path.data[..path.data.len() - 1] {
1120+
write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
1121+
}
1122+
let path = anchor(vis_did, &last_name.as_str()).to_string();
1123+
write!(f, "{}) ", path)
11201124
}
1121-
let path = anchor(did, &last_name.as_str()).to_string();
1122-
write!(f, "{}) ", path)
11231125
}
11241126
})
11251127
}

src/librustdoc/html/render/mod.rs

+18-20
Original file line numberDiff line numberDiff line change
@@ -2157,14 +2157,14 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
21572157
Some(ref src) => write!(
21582158
w,
21592159
"<tr><td><code>{}extern crate {} as {};",
2160-
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id.expect_local()),
2160+
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id),
21612161
anchor(myitem.def_id, &*src.as_str()),
21622162
name
21632163
),
21642164
None => write!(
21652165
w,
21662166
"<tr><td><code>{}extern crate {};",
2167-
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id.expect_local()),
2167+
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id),
21682168
anchor(myitem.def_id, &*name.as_str())
21692169
),
21702170
}
@@ -2175,7 +2175,7 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
21752175
write!(
21762176
w,
21772177
"<tr><td><code>{}{}</code></td></tr>",
2178-
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id.expect_local()),
2178+
myitem.visibility.print_with_space(cx.tcx(), myitem.def_id),
21792179
import.print()
21802180
);
21812181
}
@@ -2392,7 +2392,7 @@ fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::
23922392
write!(
23932393
w,
23942394
"{vis}const {name}: {typ}",
2395-
vis = it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
2395+
vis = it.visibility.print_with_space(cx.tcx(), it.def_id),
23962396
name = it.name.as_ref().unwrap(),
23972397
typ = c.type_.print(),
23982398
);
@@ -2426,7 +2426,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
24262426
write!(
24272427
w,
24282428
"{vis}static {mutability}{name}: {typ}</pre>",
2429-
vis = it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
2429+
vis = it.visibility.print_with_space(cx.tcx(), it.def_id),
24302430
mutability = s.mutability.print_with_space(),
24312431
name = it.name.as_ref().unwrap(),
24322432
typ = s.type_.print()
@@ -2437,7 +2437,7 @@ fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
24372437
fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
24382438
let header_len = format!(
24392439
"{}{}{}{}{:#}fn {}{:#}",
2440-
it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
2440+
it.visibility.print_with_space(cx.tcx(), it.def_id),
24412441
f.header.constness.print_with_space(),
24422442
f.header.asyncness.print_with_space(),
24432443
f.header.unsafety.print_with_space(),
@@ -2452,7 +2452,7 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
24522452
w,
24532453
"{vis}{constness}{asyncness}{unsafety}{abi}fn \
24542454
{name}{generics}{decl}{spotlight}{where_clause}</pre>",
2455-
vis = it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
2455+
vis = it.visibility.print_with_space(cx.tcx(), it.def_id),
24562456
constness = f.header.constness.print_with_space(),
24572457
asyncness = f.header.asyncness.print_with_space(),
24582458
unsafety = f.header.unsafety.print_with_space(),
@@ -2578,7 +2578,7 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
25782578
write!(
25792579
w,
25802580
"{}{}{}trait {}{}{}",
2581-
it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
2581+
it.visibility.print_with_space(cx.tcx(), it.def_id),
25822582
t.unsafety.print_with_space(),
25832583
if t.is_auto { "auto " } else { "" },
25842584
it.name.as_ref().unwrap(),
@@ -2896,7 +2896,7 @@ fn assoc_const(
28962896
w,
28972897
"{}{}const <a href=\"{}\" class=\"constant\"><b>{}</b></a>: {}",
28982898
extra,
2899-
it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
2899+
it.visibility.print_with_space(cx.tcx(), it.def_id),
29002900
naive_assoc_href(it, link),
29012901
it.name.as_ref().unwrap(),
29022902
ty.print()
@@ -3015,7 +3015,7 @@ fn render_assoc_item(
30153015
};
30163016
let mut header_len = format!(
30173017
"{}{}{}{}{}{:#}fn {}{:#}",
3018-
meth.visibility.print_with_space(cx.tcx(), meth.def_id.expect_local()),
3018+
meth.visibility.print_with_space(cx.tcx(), meth.def_id),
30193019
header.constness.print_with_space(),
30203020
header.asyncness.print_with_space(),
30213021
header.unsafety.print_with_space(),
@@ -3037,7 +3037,7 @@ fn render_assoc_item(
30373037
"{}{}{}{}{}{}{}fn <a href=\"{href}\" class=\"fnname\">{name}</a>\
30383038
{generics}{decl}{spotlight}{where_clause}",
30393039
if parent == ItemType::Trait { " " } else { "" },
3040-
meth.visibility.print_with_space(cx.tcx(), meth.def_id.expect_local()),
3040+
meth.visibility.print_with_space(cx.tcx(), meth.def_id),
30413041
header.constness.print_with_space(),
30423042
header.asyncness.print_with_space(),
30433043
header.unsafety.print_with_space(),
@@ -3189,7 +3189,7 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
31893189
write!(
31903190
w,
31913191
"{}enum {}{}{}",
3192-
it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
3192+
it.visibility.print_with_space(cx.tcx(), it.def_id),
31933193
it.name.as_ref().unwrap(),
31943194
e.generics.print(),
31953195
WhereClause { gens: &e.generics, indent: 0, end_newline: true }
@@ -3364,7 +3364,7 @@ fn render_struct(
33643364
write!(
33653365
w,
33663366
"{}{}{}",
3367-
it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
3367+
it.visibility.print_with_space(cx.tcx(), it.def_id),
33683368
if structhead { "struct " } else { "" },
33693369
it.name.as_ref().unwrap()
33703370
);
@@ -3384,7 +3384,7 @@ fn render_struct(
33843384
w,
33853385
"\n{} {}{}: {},",
33863386
tab,
3387-
field.visibility.print_with_space(cx.tcx(), field.def_id.expect_local()),
3387+
field.visibility.print_with_space(cx.tcx(), field.def_id),
33883388
field.name.as_ref().unwrap(),
33893389
ty.print()
33903390
);
@@ -3416,9 +3416,7 @@ fn render_struct(
34163416
write!(
34173417
w,
34183418
"{}{}",
3419-
field
3420-
.visibility
3421-
.print_with_space(cx.tcx(), field.def_id.expect_local()),
3419+
field.visibility.print_with_space(cx.tcx(), field.def_id),
34223420
ty.print()
34233421
)
34243422
}
@@ -3453,7 +3451,7 @@ fn render_union(
34533451
write!(
34543452
w,
34553453
"{}{}{}",
3456-
it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
3454+
it.visibility.print_with_space(cx.tcx(), it.def_id),
34573455
if structhead { "union " } else { "" },
34583456
it.name.as_ref().unwrap()
34593457
);
@@ -3468,7 +3466,7 @@ fn render_union(
34683466
write!(
34693467
w,
34703468
" {}{}: {},\n{}",
3471-
field.visibility.print_with_space(cx.tcx(), field.def_id.expect_local()),
3469+
field.visibility.print_with_space(cx.tcx(), field.def_id),
34723470
field.name.as_ref().unwrap(),
34733471
ty.print(),
34743472
tab
@@ -4107,7 +4105,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, cache:
41074105
write!(
41084106
w,
41094107
" {}type {};\n}}</pre>",
4110-
it.visibility.print_with_space(cx.tcx(), it.def_id.expect_local()),
4108+
it.visibility.print_with_space(cx.tcx(), it.def_id),
41114109
it.name.as_ref().unwrap(),
41124110
);
41134111

src/librustdoc/passes/collect_intra_doc_links.rs

+2-20
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use std::cell::Cell;
3131
use std::mem;
3232
use std::ops::Range;
3333

34-
use crate::clean::{self, Crate, Item, ItemLink, PrimitiveType};
34+
use crate::clean::{self, utils::find_closest_parent_module, Crate, Item, ItemLink, PrimitiveType};
3535
use crate::core::DocContext;
3636
use crate::fold::DocFolder;
3737
use crate::html::markdown::markdown_links;
@@ -774,25 +774,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
774774
} else if item.def_id.is_top_level_module() {
775775
Some(item.def_id)
776776
} else {
777-
let mut current = item.def_id;
778-
// The immediate parent might not always be a module.
779-
// Find the first parent which is.
780-
loop {
781-
if let Some(parent) = self.cx.tcx.parent(current) {
782-
if self.cx.tcx.def_kind(parent) == DefKind::Mod {
783-
break Some(parent);
784-
}
785-
current = parent;
786-
} else {
787-
debug!(
788-
"{:?} has no parent (kind={:?}, original was {:?})",
789-
current,
790-
self.cx.tcx.def_kind(current),
791-
item.def_id
792-
);
793-
break None;
794-
}
795-
}
777+
find_closest_parent_module(self.cx.tcx, item.def_id)
796778
};
797779

798780
if parent_node.is_some() {

src/test/rustdoc/decl_macro_priv.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#![feature(decl_macro)]
44

5-
// @has decl_macro_priv/macro.crate_macro.html //pre 'pub(crate) macro crate_macro() {'
5+
// @has decl_macro_priv/macro.crate_macro.html //pre 'macro crate_macro() {'
66
// @has - //pre '...'
77
// @has - //pre '}'
88
pub(crate) macro crate_macro() {}

src/test/rustdoc/pub-restricted.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@
66

77
// @has 'foo/struct.FooPublic.html' '//pre' 'pub struct FooPublic'
88
pub struct FooPublic;
9-
// @has 'foo/struct.FooJustCrate.html' '//pre' 'pub(crate) struct FooJustCrate'
9+
// @has 'foo/struct.FooJustCrate.html' '//pre' 'struct FooJustCrate'
1010
crate struct FooJustCrate;
11-
// @has 'foo/struct.FooPubCrate.html' '//pre' 'pub(crate) struct FooPubCrate'
11+
// @has 'foo/struct.FooPubCrate.html' '//pre' 'struct FooPubCrate'
1212
pub(crate) struct FooPubCrate;
13-
// @has 'foo/struct.FooSelf.html' '//pre' 'pub(crate) struct FooSelf'
13+
// @has 'foo/struct.FooSelf.html' '//pre' 'struct FooSelf'
1414
pub(self) struct FooSelf;
15-
// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(crate) struct FooInSelf'
15+
// @has 'foo/struct.FooInSelf.html' '//pre' 'struct FooInSelf'
1616
pub(in self) struct FooInSelf;
1717
mod a {
18-
// @has 'foo/a/struct.FooSuper.html' '//pre' 'pub(crate) struct FooSuper'
19-
pub(super) struct FooSuper;
20-
// @has 'foo/a/struct.FooInSuper.html' '//pre' 'pub(crate) struct FooInSuper'
21-
pub(in super) struct FooInSuper;
22-
// @has 'foo/a/struct.FooInA.html' '//pre' 'pub(in a) struct FooInA'
23-
pub(in a) struct FooInA;
18+
// @has 'foo/a/struct.FooASuper.html' '//pre' 'pub(crate) struct FooASuper'
19+
pub(super) struct FooASuper;
20+
// @has 'foo/a/struct.FooAInSuper.html' '//pre' 'pub(crate) struct FooAInSuper'
21+
pub(in super) struct FooAInSuper;
22+
// @has 'foo/a/struct.FooAInA.html' '//pre' 'struct FooAInA'
23+
pub(in a) struct FooAInA;
2424
mod b {
25-
// @has 'foo/a/b/struct.FooInSelfSuperB.html' '//pre' 'pub(in a::b) struct FooInSelfSuperB'
26-
pub(in a::b) struct FooInSelfSuperB;
27-
// @has 'foo/a/b/struct.FooInSuperSuper.html' '//pre' 'pub(crate) struct FooInSuperSuper'
28-
pub(in super::super) struct FooInSuperSuper;
29-
// @has 'foo/a/b/struct.FooInAB.html' '//pre' 'pub(in a::b) struct FooInAB'
30-
pub(in a::b) struct FooInAB;
25+
// @has 'foo/a/b/struct.FooBSuper.html' '//pre' 'pub(super) struct FooBSuper'
26+
pub(super) struct FooBSuper;
27+
// @has 'foo/a/b/struct.FooBInSuperSuper.html' '//pre' 'pub(crate) struct FooBInSuperSuper'
28+
pub(in super::super) struct FooBInSuperSuper;
29+
// @has 'foo/a/b/struct.FooBInAB.html' '//pre' 'struct FooBInAB'
30+
pub(in a::b) struct FooBInAB;
3131
}
3232
}

0 commit comments

Comments
 (0)