diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 007938e86ed9d..0d628d47766b3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -17,7 +17,7 @@ pub use self::ItemEnum::*; pub use self::TyParamBound::*; pub use self::SelfTy::*; pub use self::FunctionRetTy::*; -pub use self::Visibility::*; +pub use self::Visibility::{Public, Inherited}; use syntax; use rustc_target::spec::abi::Abi; @@ -2976,11 +2976,22 @@ impl<'tcx> Clean for ty::FieldDef { pub enum Visibility { Public, Inherited, + Crate, + Restricted(DefId, Path), } impl Clean> for hir::Visibility { - fn clean(&self, _: &DocContext) -> Option { - Some(if *self == hir::Visibility::Public { Public } else { Inherited }) + fn clean(&self, cx: &DocContext) -> Option { + Some(match *self { + hir::Visibility::Public => Visibility::Public, + hir::Visibility::Inherited => Visibility::Inherited, + hir::Visibility::Crate => Visibility::Crate, + hir::Visibility::Restricted { ref path, .. } => { + let path = path.clean(cx); + let did = register_def(cx, path.def); + Visibility::Restricted(did, path) + } + }) } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index a9a4c5113747e..2db57c97dd466 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -927,8 +927,19 @@ impl<'a> fmt::Display for Method<'a> { impl<'a> fmt::Display for VisSpace<'a> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self.get() { - Some(clean::Public) => write!(f, "pub "), - Some(clean::Inherited) | None => Ok(()) + Some(clean::Public) => f.write_str("pub "), + Some(clean::Inherited) | None => Ok(()), + Some(clean::Visibility::Crate) => write!(f, "pub(crate) "), + Some(clean::Visibility::Restricted(did, ref path)) => { + f.write_str("pub(")?; + if path.segments.len() != 1 + || (path.segments[0].name != "self" && path.segments[0].name != "super") + { + f.write_str("in ")?; + } + resolved_path(f, did, path, true, false)?; + f.write_str(") ") + } } } } diff --git a/src/test/rustdoc/pub-restricted.rs b/src/test/rustdoc/pub-restricted.rs new file mode 100644 index 0000000000000..cc8f628cad44b --- /dev/null +++ b/src/test/rustdoc/pub-restricted.rs @@ -0,0 +1,44 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// ignore-tidy-linelength + +// compile-flags: --document-private-items + +#![feature(crate_visibility_modifier)] + +#![crate_name = "foo"] + +// @has 'foo/struct.FooPublic.html' '//pre' 'pub struct FooPublic' +pub struct FooPublic; +// @has 'foo/struct.FooJustCrate.html' '//pre' 'pub(crate) struct FooJustCrate' +crate struct FooJustCrate; +// @has 'foo/struct.FooPubCrate.html' '//pre' 'pub(crate) struct FooPubCrate' +pub(crate) struct FooPubCrate; +// @has 'foo/struct.FooSelf.html' '//pre' 'pub(self) struct FooSelf' +pub(self) struct FooSelf; +// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(self) struct FooInSelf' +pub(in self) struct FooInSelf; +mod a { + // @has 'foo/a/struct.FooSuper.html' '//pre' 'pub(super) struct FooSuper' + pub(super) struct FooSuper; + // @has 'foo/a/struct.FooInSuper.html' '//pre' 'pub(super) struct FooInSuper' + pub(in super) struct FooInSuper; + // @has 'foo/a/struct.FooInA.html' '//pre' 'pub(in a) struct FooInA' + pub(in a) struct FooInA; + mod b { + // @has 'foo/a/b/struct.FooInSelfSuperB.html' '//pre' 'pub(in self::super::b) struct FooInSelfSuperB' + pub(in self::super::b) struct FooInSelfSuperB; + // @has 'foo/a/b/struct.FooInSuperSuper.html' '//pre' 'pub(in super::super) struct FooInSuperSuper' + pub(in super::super) struct FooInSuperSuper; + // @has 'foo/a/b/struct.FooInAB.html' '//pre' 'pub(in a::b) struct FooInAB' + pub(in a::b) struct FooInAB; + } +}