Skip to content

Commit 6c28ffb

Browse files
committed
Use DefPath for clean::Visibility, not clean::Path
Visibility needs much less information than a full path, since modules can never have generics. This allows constructing a Visibility from only a DefId. Note that this means that paths are now normalized to their DefPath. In other words, `pub(self)` or `pub(super)` now always shows `pub(in path)` instead of preserving the original text.
1 parent c919f49 commit 6c28ffb

File tree

5 files changed

+37
-22
lines changed

5 files changed

+37
-22
lines changed

src/librustdoc/clean/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1812,7 +1812,7 @@ impl Clean<Visibility> for hir::Visibility<'_> {
18121812
hir::VisibilityKind::Restricted { ref path, .. } => {
18131813
let path = path.clean(cx);
18141814
let did = register_res(cx, path.res);
1815-
Visibility::Restricted(did, path)
1815+
Visibility::Restricted(did, cx.tcx.def_path(did))
18161816
}
18171817
}
18181818
}

src/librustdoc/clean/types.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -1460,12 +1460,18 @@ impl From<hir::PrimTy> for PrimitiveType {
14601460
}
14611461
}
14621462

1463-
#[derive(Clone, PartialEq, Eq, Debug)]
1463+
#[derive(Clone, Debug)]
14641464
crate enum Visibility {
14651465
Public,
14661466
Inherited,
14671467
Crate,
1468-
Restricted(DefId, Path),
1468+
Restricted(DefId, rustc_hir::definitions::DefPath),
1469+
}
1470+
1471+
impl Visibility {
1472+
crate fn is_public(&self) -> bool {
1473+
matches!(self, Visibility::Public)
1474+
}
14691475
}
14701476

14711477
#[derive(Clone, Debug)]

src/librustdoc/html/format.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::fmt;
1111

1212
use rustc_data_structures::fx::FxHashSet;
1313
use rustc_hir as hir;
14-
use rustc_span::def_id::DefId;
14+
use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
1515
use rustc_target::spec::abi::Abi;
1616

1717
use crate::clean::{self, PrimitiveType};
@@ -1089,19 +1089,32 @@ impl Function<'_> {
10891089

10901090
impl clean::Visibility {
10911091
crate fn print_with_space(&self) -> impl fmt::Display + '_ {
1092+
use rustc_span::symbol::kw;
1093+
10921094
display_fn(move |f| match *self {
10931095
clean::Public => f.write_str("pub "),
10941096
clean::Inherited => Ok(()),
10951097
clean::Visibility::Crate => write!(f, "pub(crate) "),
1098+
// If this is `pub(crate)`, `path` will be empty.
1099+
clean::Visibility::Restricted(did, _) if did.index == CRATE_DEF_INDEX => {
1100+
write!(f, "pub(crate) ")
1101+
}
10961102
clean::Visibility::Restricted(did, ref path) => {
10971103
f.write_str("pub(")?;
1098-
if path.segments.len() != 1
1099-
|| (path.segments[0].name != "self" && path.segments[0].name != "super")
1104+
debug!("path={:?}", path);
1105+
let first_name =
1106+
path.data[0].data.get_opt_name().expect("modules are always named");
1107+
if path.data.len() != 1 || (first_name != kw::SelfLower && first_name != kw::Super)
11001108
{
11011109
f.write_str("in ")?;
11021110
}
1103-
resolved_path(f, did, path, true, false)?;
1104-
f.write_str(") ")
1111+
// modified from `resolved_path()` to work with `DefPathData`
1112+
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
1113+
for seg in &path.data[..path.data.len() - 1] {
1114+
write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
1115+
}
1116+
let path = anchor(did, &last_name.as_str()).to_string();
1117+
write!(f, "{}) ", path)
11051118
}
11061119
})
11071120
}

src/librustdoc/passes/stripper.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@ impl<'a> DocFolder for Stripper<'a> {
5050
}
5151

5252
clean::StructFieldItem(..) => {
53-
if i.visibility != clean::Public {
53+
if !i.visibility.is_public() {
5454
return StripItem(i).strip();
5555
}
5656
}
5757

5858
clean::ModuleItem(..) => {
59-
if i.def_id.is_local() && i.visibility != clean::Public {
59+
if i.def_id.is_local() && !i.visibility.is_public() {
6060
debug!("Stripper: stripping module {:?}", i.name);
6161
let old = mem::replace(&mut self.update_retained, false);
6262
let ret = StripItem(self.fold_item_recur(i).unwrap()).strip();
@@ -163,9 +163,7 @@ crate struct ImportStripper;
163163
impl DocFolder for ImportStripper {
164164
fn fold_item(&mut self, i: Item) -> Option<Item> {
165165
match i.kind {
166-
clean::ExternCrateItem(..) | clean::ImportItem(..) if i.visibility != clean::Public => {
167-
None
168-
}
166+
clean::ExternCrateItem(..) | clean::ImportItem(..) if !i.visibility.is_public() => None,
169167
_ => self.fold_item_recur(i),
170168
}
171169
}

src/test/rustdoc/pub-restricted.rs

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// ignore-tidy-linelength
2-
31
// compile-flags: --document-private-items
42

53
#![feature(crate_visibility_modifier)]
@@ -12,21 +10,21 @@ pub struct FooPublic;
1210
crate struct FooJustCrate;
1311
// @has 'foo/struct.FooPubCrate.html' '//pre' 'pub(crate) struct FooPubCrate'
1412
pub(crate) struct FooPubCrate;
15-
// @has 'foo/struct.FooSelf.html' '//pre' 'pub(self) struct FooSelf'
13+
// @has 'foo/struct.FooSelf.html' '//pre' 'pub(crate) struct FooSelf'
1614
pub(self) struct FooSelf;
17-
// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(self) struct FooInSelf'
15+
// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(crate) struct FooInSelf'
1816
pub(in self) struct FooInSelf;
1917
mod a {
20-
// @has 'foo/a/struct.FooSuper.html' '//pre' 'pub(super) struct FooSuper'
18+
// @has 'foo/a/struct.FooSuper.html' '//pre' 'pub(crate) struct FooSuper'
2119
pub(super) struct FooSuper;
22-
// @has 'foo/a/struct.FooInSuper.html' '//pre' 'pub(super) struct FooInSuper'
20+
// @has 'foo/a/struct.FooInSuper.html' '//pre' 'pub(crate) struct FooInSuper'
2321
pub(in super) struct FooInSuper;
2422
// @has 'foo/a/struct.FooInA.html' '//pre' 'pub(in a) struct FooInA'
2523
pub(in a) struct FooInA;
2624
mod b {
27-
// @has 'foo/a/b/struct.FooInSelfSuperB.html' '//pre' 'pub(in self::super::b) struct FooInSelfSuperB'
28-
pub(in self::super::b) struct FooInSelfSuperB;
29-
// @has 'foo/a/b/struct.FooInSuperSuper.html' '//pre' 'pub(in super::super) struct FooInSuperSuper'
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'
3028
pub(in super::super) struct FooInSuperSuper;
3129
// @has 'foo/a/b/struct.FooInAB.html' '//pre' 'pub(in a::b) struct FooInAB'
3230
pub(in a::b) struct FooInAB;

0 commit comments

Comments
 (0)