Auto merge of #77820 - jyn514:from-inner, r=petrochenkov

Add `Item::from_def_id_and_kind` to reduce duplication in rustdoc

This makes it harder to make typos, and also makes it much more clear what's intentionally different rather than a typo (look for `what_rustc_thinks`).

Found this while working on https://github.com/rust-lang/rust/issues/76998, I really didn't want to add `const_visibility` in 20 different places.

r? `@GuillaumeGomez`
This commit is contained in:
bors 2020-11-18 03:56:18 +00:00
commit c4f836ad1a
10 changed files with 274 additions and 446 deletions

View File

@ -806,25 +806,34 @@ impl<'hir> Map<'hir> {
/// Given a node ID, gets a list of attributes associated with the AST
/// corresponding to the node-ID.
pub fn attrs(&self, id: HirId) -> &'hir [ast::Attribute] {
let attrs = match self.find_entry(id).map(|entry| entry.node) {
Some(Node::Param(a)) => Some(&a.attrs[..]),
Some(Node::Local(l)) => Some(&l.attrs[..]),
Some(Node::Item(i)) => Some(&i.attrs[..]),
Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
Some(Node::TraitItem(ref ti)) => Some(&ti.attrs[..]),
Some(Node::ImplItem(ref ii)) => Some(&ii.attrs[..]),
Some(Node::Variant(ref v)) => Some(&v.attrs[..]),
Some(Node::Field(ref f)) => Some(&f.attrs[..]),
Some(Node::Expr(ref e)) => Some(&*e.attrs),
Some(Node::Stmt(ref s)) => Some(s.kind.attrs(|id| self.item(id.id))),
Some(Node::Arm(ref a)) => Some(&*a.attrs),
Some(Node::GenericParam(param)) => Some(&param.attrs[..]),
let attrs = self.find_entry(id).map(|entry| match entry.node {
Node::Param(a) => &a.attrs[..],
Node::Local(l) => &l.attrs[..],
Node::Item(i) => &i.attrs[..],
Node::ForeignItem(fi) => &fi.attrs[..],
Node::TraitItem(ref ti) => &ti.attrs[..],
Node::ImplItem(ref ii) => &ii.attrs[..],
Node::Variant(ref v) => &v.attrs[..],
Node::Field(ref f) => &f.attrs[..],
Node::Expr(ref e) => &*e.attrs,
Node::Stmt(ref s) => s.kind.attrs(|id| self.item(id.id)),
Node::Arm(ref a) => &*a.attrs,
Node::GenericParam(param) => &param.attrs[..],
// Unit/tuple structs/variants take the attributes straight from
// the struct/variant definition.
Some(Node::Ctor(..)) => return self.attrs(self.get_parent_item(id)),
Some(Node::Crate(item)) => Some(&item.attrs[..]),
_ => None,
};
Node::Ctor(..) => self.attrs(self.get_parent_item(id)),
Node::Crate(item) => &item.attrs[..],
Node::MacroDef(def) => def.attrs,
Node::AnonConst(..)
| Node::PathSegment(..)
| Node::Ty(..)
| Node::Pat(..)
| Node::Binding(..)
| Node::TraitRef(..)
| Node::Block(..)
| Node::Lifetime(..)
| Node::Visibility(..) => &[],
});
attrs.unwrap_or(&[])
}

View File

@ -124,16 +124,8 @@ crate fn try_inline(
let attrs = merge_attrs(cx, Some(parent_module), target_attrs, attrs_clone);
cx.renderinfo.borrow_mut().inlined.insert(did);
ret.push(clean::Item {
source: cx.tcx.def_span(did).clean(cx),
name: Some(name.clean(cx)),
attrs,
kind,
visibility: clean::Public,
stability: cx.tcx.lookup_stability(did).cloned(),
deprecation: cx.tcx.lookup_deprecation(did).clean(cx),
def_id: did,
});
let what_rustc_thinks = clean::Item::from_def_id_and_parts(did, Some(name), kind, cx);
ret.push(clean::Item { attrs, ..what_rustc_thinks });
Some(ret)
}
@ -443,8 +435,10 @@ crate fn build_impl(
debug!("build_impl: impl {:?} for {:?}", trait_.def_id(), for_.def_id());
ret.push(clean::Item {
kind: clean::ImplItem(clean::Impl {
ret.push(clean::Item::from_def_id_and_parts(
did,
None,
clean::ImplItem(clean::Impl {
unsafety: hir::Unsafety::Normal,
generics,
provided_trait_methods: provided,
@ -455,14 +449,8 @@ crate fn build_impl(
synthetic: false,
blanket_impl: None,
}),
source: tcx.def_span(did).clean(cx),
name: None,
attrs,
visibility: clean::Inherited,
stability: tcx.lookup_stability(did).cloned(),
deprecation: tcx.lookup_deprecation(did).clean(cx),
def_id: did,
});
cx,
));
}
fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>) -> clean::Module {

View File

@ -223,12 +223,6 @@ impl Clean<ExternalCrate> for CrateNum {
impl Clean<Item> for doctree::Module<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let name = if self.name.is_some() {
self.name.expect("No name provided").clean(cx)
} else {
String::new()
};
// maintain a stack of mod ids, for doc comment path resolution
// but we also need to resolve the module's own docs based on whether its docs were written
// inside or outside the module, so check for that
@ -268,15 +262,17 @@ impl Clean<Item> for doctree::Module<'_> {
}
};
let what_rustc_thinks = Item::from_hir_id_and_parts(
self.id,
self.name,
ModuleItem(Module { is_crate: self.is_crate, items }),
cx,
);
Item {
name: Some(name),
name: Some(what_rustc_thinks.name.unwrap_or_default()),
attrs,
source: span.clean(cx),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
kind: ModuleItem(Module { is_crate: self.is_crate, items }),
..what_rustc_thinks
}
}
}
@ -897,31 +893,26 @@ impl Clean<Item> for doctree::Function<'_> {
let (generics, decl) =
enter_impl_trait(cx, || (self.generics.clean(cx), (self.decl, self.body).clean(cx)));
let did = cx.tcx.hir().local_def_id(self.id);
let constness = if is_const_fn(cx.tcx, did.to_def_id())
&& !is_unstable_const_fn(cx.tcx, did.to_def_id()).is_some()
let did = cx.tcx.hir().local_def_id(self.id).to_def_id();
let constness = if is_const_fn(cx.tcx, did) && !is_unstable_const_fn(cx.tcx, did).is_some()
{
hir::Constness::Const
} else {
hir::Constness::NotConst
};
let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
def_id: did.to_def_id(),
kind: FunctionItem(Function {
Item::from_def_id_and_parts(
did,
Some(self.name),
FunctionItem(Function {
decl,
generics,
header: hir::FnHeader { constness, ..self.header },
all_types,
ret_types,
}),
}
cx,
)
}
}
@ -1013,15 +1004,10 @@ impl Clean<Item> for doctree::Trait<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let attrs = self.attrs.clean(cx);
let is_spotlight = attrs.has_doc_flag(sym::spotlight);
Item {
name: Some(self.name.clean(cx)),
attrs,
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind: TraitItem(Trait {
Item::from_hir_id_and_parts(
self.id,
Some(self.name),
TraitItem(Trait {
unsafety: self.unsafety,
items: self.items.iter().map(|ti| ti.clean(cx)).collect(),
generics: self.generics.clean(cx),
@ -1029,26 +1015,22 @@ impl Clean<Item> for doctree::Trait<'_> {
is_spotlight,
is_auto: self.is_auto.clean(cx),
}),
}
cx,
)
}
}
impl Clean<Item> for doctree::TraitAlias<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let attrs = self.attrs.clean(cx);
Item {
name: Some(self.name.clean(cx)),
attrs,
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind: TraitAliasItem(TraitAlias {
Item::from_hir_id_and_parts(
self.id,
Some(self.name),
TraitAliasItem(TraitAlias {
generics: self.generics.clean(cx),
bounds: self.bounds.clean(cx),
}),
}
cx,
)
}
}
@ -1098,15 +1080,15 @@ impl Clean<TypeKind> for hir::def::DefKind {
impl Clean<Item> for hir::TraitItem<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let local_did = cx.tcx.hir().local_def_id(self.hir_id);
let kind = match self.kind {
let local_did = cx.tcx.hir().local_def_id(self.hir_id).to_def_id();
let inner = match self.kind {
hir::TraitItemKind::Const(ref ty, default) => {
AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx, e)))
}
hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => {
let mut m = (sig, &self.generics, body).clean(cx);
if m.header.constness == hir::Constness::Const
&& is_unstable_const_fn(cx.tcx, local_did.to_def_id()).is_some()
&& is_unstable_const_fn(cx.tcx, local_did).is_some()
{
m.header.constness = hir::Constness::NotConst;
}
@ -1119,7 +1101,7 @@ impl Clean<Item> for hir::TraitItem<'_> {
let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
let mut t = Function { header: sig.header, decl, generics, all_types, ret_types };
if t.header.constness == hir::Constness::Const
&& is_unstable_const_fn(cx.tcx, local_did.to_def_id()).is_some()
&& is_unstable_const_fn(cx.tcx, local_did).is_some()
{
t.header.constness = hir::Constness::NotConst;
}
@ -1129,30 +1111,21 @@ impl Clean<Item> for hir::TraitItem<'_> {
AssocTypeItem(bounds.clean(cx), default.clean(cx))
}
};
Item {
name: Some(self.ident.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: local_did.to_def_id(),
visibility: Visibility::Inherited,
stability: get_stability(cx, local_did.to_def_id()),
deprecation: get_deprecation(cx, local_did.to_def_id()),
kind,
}
Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx)
}
}
impl Clean<Item> for hir::ImplItem<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let local_did = cx.tcx.hir().local_def_id(self.hir_id);
let kind = match self.kind {
let local_did = cx.tcx.hir().local_def_id(self.hir_id).to_def_id();
let inner = match self.kind {
hir::ImplItemKind::Const(ref ty, expr) => {
AssocConstItem(ty.clean(cx), Some(print_const_expr(cx, expr)))
}
hir::ImplItemKind::Fn(ref sig, body) => {
let mut m = (sig, &self.generics, body).clean(cx);
if m.header.constness == hir::Constness::Const
&& is_unstable_const_fn(cx.tcx, local_did.to_def_id()).is_some()
&& is_unstable_const_fn(cx.tcx, local_did).is_some()
{
m.header.constness = hir::Constness::NotConst;
}
@ -1164,16 +1137,7 @@ impl Clean<Item> for hir::ImplItem<'_> {
TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true)
}
};
Item {
name: Some(self.ident.name.clean(cx)),
source: self.span.clean(cx),
attrs: self.attrs.clean(cx),
def_id: local_did.to_def_id(),
visibility: self.vis.clean(cx),
stability: get_stability(cx, local_did.to_def_id()),
deprecation: get_deprecation(cx, local_did.to_def_id()),
kind,
}
Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx)
}
}
@ -1329,21 +1293,7 @@ impl Clean<Item> for ty::AssocItem {
}
};
let visibility = match self.container {
ty::ImplContainer(_) => self.vis.clean(cx),
ty::TraitContainer(_) => Inherited,
};
Item {
name: Some(self.ident.name.clean(cx)),
visibility,
stability: get_stability(cx, self.def_id),
deprecation: get_deprecation(cx, self.def_id),
def_id: self.def_id,
attrs: inline::load_attrs(cx, self.def_id).clean(cx),
source: cx.tcx.def_span(self.def_id).clean(cx),
kind,
}
Item::from_def_id_and_parts(self.def_id, Some(self.ident.name), kind, cx)
}
}
@ -1773,33 +1723,27 @@ impl<'tcx> Clean<Constant> for ty::Const<'tcx> {
impl Clean<Item> for hir::StructField<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let local_did = cx.tcx.hir().local_def_id(self.hir_id);
Item {
name: Some(self.ident.name).clean(cx),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
visibility: self.vis.clean(cx),
stability: get_stability(cx, local_did.to_def_id()),
deprecation: get_deprecation(cx, local_did.to_def_id()),
def_id: local_did.to_def_id(),
kind: StructFieldItem(self.ty.clean(cx)),
}
let what_rustc_thinks = Item::from_hir_id_and_parts(
self.hir_id,
Some(self.ident.name),
StructFieldItem(self.ty.clean(cx)),
cx,
);
// Don't show `pub` for fields on enum variants; they are always public
Item { visibility: self.vis.clean(cx), ..what_rustc_thinks }
}
}
impl Clean<Item> for ty::FieldDef {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.ident.name).clean(cx),
attrs: cx.tcx.get_attrs(self.did).clean(cx),
source: cx.tcx.def_span(self.did).clean(cx),
visibility: self.vis.clean(cx),
stability: get_stability(cx, self.did),
deprecation: get_deprecation(cx, self.did),
def_id: self.did,
kind: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)),
}
let what_rustc_thinks = Item::from_def_id_and_parts(
self.did,
Some(self.ident.name),
StructFieldItem(cx.tcx.type_of(self.did).clean(cx)),
cx,
);
// Don't show `pub` for fields on enum variants; they are always public
Item { visibility: self.vis.clean(cx), ..what_rustc_thinks }
}
}
@ -1808,59 +1752,60 @@ impl Clean<Visibility> for hir::Visibility<'_> {
match self.node {
hir::VisibilityKind::Public => Visibility::Public,
hir::VisibilityKind::Inherited => Visibility::Inherited,
hir::VisibilityKind::Crate(_) => Visibility::Crate,
hir::VisibilityKind::Crate(_) => {
let krate = DefId::local(CRATE_DEF_INDEX);
Visibility::Restricted(krate, cx.tcx.def_path(krate))
}
hir::VisibilityKind::Restricted { ref path, .. } => {
let path = path.clean(cx);
let did = register_res(cx, path.res);
Visibility::Restricted(did, path)
Visibility::Restricted(did, cx.tcx.def_path(did))
}
}
}
}
impl Clean<Visibility> for ty::Visibility {
fn clean(&self, _: &DocContext<'_>) -> Visibility {
if *self == ty::Visibility::Public { Public } else { Inherited }
fn clean(&self, cx: &DocContext<'_>) -> Visibility {
match *self {
ty::Visibility::Public => Visibility::Public,
ty::Visibility::Invisible => Visibility::Inherited,
ty::Visibility::Restricted(module) => {
Visibility::Restricted(module, cx.tcx.def_path(module))
}
}
}
}
impl Clean<Item> for doctree::Struct<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind: StructItem(Struct {
Item::from_hir_id_and_parts(
self.id,
Some(self.name),
StructItem(Struct {
struct_type: self.struct_type,
generics: self.generics.clean(cx),
fields: self.fields.clean(cx),
fields_stripped: false,
}),
}
cx,
)
}
}
impl Clean<Item> for doctree::Union<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind: UnionItem(Union {
Item::from_hir_id_and_parts(
self.id,
Some(self.name),
UnionItem(Union {
struct_type: self.struct_type,
generics: self.generics.clean(cx),
fields: self.fields.clean(cx),
fields_stripped: false,
}),
}
cx,
)
}
}
@ -1876,35 +1821,29 @@ impl Clean<VariantStruct> for rustc_hir::VariantData<'_> {
impl Clean<Item> for doctree::Enum<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind: EnumItem(Enum {
Item::from_hir_id_and_parts(
self.id,
Some(self.name),
EnumItem(Enum {
variants: self.variants.iter().map(|v| v.clean(cx)).collect(),
generics: self.generics.clean(cx),
variants_stripped: false,
}),
}
cx,
)
}
}
impl Clean<Item> for doctree::Variant<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
visibility: Inherited,
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
kind: VariantItem(Variant { kind: self.def.clean(cx) }),
}
let what_rustc_thinks = Item::from_hir_id_and_parts(
self.id,
Some(self.name),
VariantItem(Variant { kind: self.def.clean(cx) }),
cx,
);
// don't show `pub` for variants, which are always public
Item { visibility: Inherited, ..what_rustc_thinks }
}
}
@ -1925,7 +1864,7 @@ impl Clean<Item> for ty::VariantDef {
source: cx.tcx.def_span(field.did).clean(cx),
name: Some(field.ident.name.clean(cx)),
attrs: cx.tcx.get_attrs(field.did).clean(cx),
visibility: field.vis.clean(cx),
visibility: Visibility::Inherited,
def_id: field.did,
stability: get_stability(cx, field.did),
deprecation: get_deprecation(cx, field.did),
@ -1934,16 +1873,14 @@ impl Clean<Item> for ty::VariantDef {
.collect(),
}),
};
Item {
name: Some(self.ident.clean(cx)),
attrs: inline::load_attrs(cx, self.def_id).clean(cx),
source: cx.tcx.def_span(self.def_id).clean(cx),
visibility: Inherited,
def_id: self.def_id,
kind: VariantItem(Variant { kind }),
stability: get_stability(cx, self.def_id),
deprecation: get_deprecation(cx, self.def_id),
}
let what_rustc_thinks = Item::from_def_id_and_parts(
self.def_id,
Some(self.ident.name),
VariantItem(Variant { kind }),
cx,
);
// don't show `pub` for fields, which are always public
Item { visibility: Inherited, ..what_rustc_thinks }
}
}
@ -2048,34 +1985,26 @@ impl Clean<Item> for doctree::Typedef<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let type_ = self.ty.clean(cx);
let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did));
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false),
}
Item::from_hir_id_and_parts(
self.id,
Some(self.name),
TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false),
cx,
)
}
}
impl Clean<Item> for doctree::OpaqueTy<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind: OpaqueTyItem(OpaqueTy {
Item::from_hir_id_and_parts(
self.id,
Some(self.name),
OpaqueTyItem(OpaqueTy {
bounds: self.opaque_ty.bounds.clean(cx),
generics: self.opaque_ty.generics.clean(cx),
}),
}
cx,
)
}
}
@ -2091,42 +2020,34 @@ impl Clean<BareFunctionDecl> for hir::BareFnTy<'_> {
impl Clean<Item> for doctree::Static<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
debug!("cleaning static {}: {:?}", self.name.clean(cx), self);
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind: StaticItem(Static {
Item::from_hir_id_and_parts(
self.id,
Some(self.name),
StaticItem(Static {
type_: self.type_.clean(cx),
mutability: self.mutability,
expr: print_const_expr(cx, self.expr),
}),
}
cx,
)
}
}
impl Clean<Item> for doctree::Constant<'_> {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let def_id = cx.tcx.hir().local_def_id(self.id);
let def_id = cx.tcx.hir().local_def_id(self.id).to_def_id();
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: def_id.to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind: ConstantItem(Constant {
Item::from_def_id_and_parts(
def_id,
Some(self.name),
ConstantItem(Constant {
type_: self.type_.clean(cx),
expr: print_const_expr(cx, self.expr),
value: print_evaluated_const(cx, def_id.to_def_id()),
value: print_evaluated_const(cx, def_id),
is_literal: is_literal_expr(cx, self.expr.hir_id),
}),
}
cx,
)
}
}
@ -2355,34 +2276,19 @@ impl Clean<Item> for doctree::ForeignItem<'_> {
hir::ForeignItemKind::Type => ForeignTypeItem,
};
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
visibility: self.vis.clean(cx),
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
kind,
}
Item::from_hir_id_and_parts(self.id, Some(self.name), kind, cx)
}
}
impl Clean<Item> for doctree::Macro<'_> {
impl Clean<Item> for doctree::Macro {
fn clean(&self, cx: &DocContext<'_>) -> Item {
let name = self.name.clean(cx);
Item {
name: Some(name.clone()),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
visibility: Public,
stability: cx.stability(self.hid),
deprecation: cx.deprecation(self.hid).clean(cx),
def_id: self.def_id,
kind: MacroItem(Macro {
Item::from_def_id_and_parts(
self.def_id,
Some(self.name),
MacroItem(Macro {
source: format!(
"macro_rules! {} {{\n{}}}",
name,
self.name,
self.matchers
.iter()
.map(|span| { format!(" {} => {{ ... }};\n", span.to_src(cx)) })
@ -2390,22 +2296,19 @@ impl Clean<Item> for doctree::Macro<'_> {
),
imported_from: self.imported_from.clean(cx),
}),
}
cx,
)
}
}
impl Clean<Item> for doctree::ProcMacro<'_> {
impl Clean<Item> for doctree::ProcMacro {
fn clean(&self, cx: &DocContext<'_>) -> Item {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.span.clean(cx),
visibility: Public,
stability: cx.stability(self.id),
deprecation: cx.deprecation(self.id).clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id).to_def_id(),
kind: ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }),
}
Item::from_hir_id_and_parts(
self.id,
Some(self.name),
ProcMacroItem(ProcMacro { kind: self.kind, helpers: self.helpers.clean(cx) }),
cx,
)
}
}

View File

@ -112,6 +112,48 @@ impl Item {
self.attrs.doc_value()
}
/// Convenience wrapper around [`Self::from_def_id_and_parts`] which converts
/// `hir_id` to a [`DefId`]
pub fn from_hir_id_and_parts(
hir_id: hir::HirId,
name: Option<Symbol>,
kind: ItemKind,
cx: &DocContext<'_>,
) -> Item {
Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx)
}
pub fn from_def_id_and_parts(
def_id: DefId,
name: Option<Symbol>,
kind: ItemKind,
cx: &DocContext<'_>,
) -> Item {
use super::Clean;
debug!("name={:?}, def_id={:?}", name, def_id);
// `span_if_local()` lies about functions and only gives the span of the function signature
let source = def_id.as_local().map_or_else(
|| cx.tcx.def_span(def_id),
|local| {
let hir = cx.tcx.hir();
hir.span_with_body(hir.local_def_id_to_hir_id(local))
},
);
Item {
def_id,
kind,
name: name.clean(cx),
source: source.clean(cx),
attrs: cx.tcx.get_attrs(def_id).clean(cx),
visibility: cx.tcx.visibility(def_id).clean(cx),
stability: cx.tcx.lookup_stability(def_id).cloned(),
deprecation: cx.tcx.lookup_deprecation(def_id).clean(cx),
}
}
/// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
/// with newlines.
crate fn collapsed_doc_value(&self) -> Option<String> {
@ -1460,12 +1502,17 @@ impl From<hir::PrimTy> for PrimitiveType {
}
}
#[derive(Clone, PartialEq, Eq, Debug)]
#[derive(Clone, Debug)]
crate enum Visibility {
Public,
Inherited,
Crate,
Restricted(DefId, Path),
Restricted(DefId, rustc_hir::definitions::DefPath),
}
impl Visibility {
crate fn is_public(&self) -> bool {
matches!(self, Visibility::Public)
}
}
#[derive(Clone, Debug)]

View File

@ -28,25 +28,19 @@ crate struct Module<'hir> {
crate statics: Vec<Static<'hir>>,
crate constants: Vec<Constant<'hir>>,
crate traits: Vec<Trait<'hir>>,
crate vis: &'hir hir::Visibility<'hir>,
crate impls: Vec<Impl<'hir>>,
crate foreigns: Vec<ForeignItem<'hir>>,
crate macros: Vec<Macro<'hir>>,
crate proc_macros: Vec<ProcMacro<'hir>>,
crate macros: Vec<Macro>,
crate proc_macros: Vec<ProcMacro>,
crate trait_aliases: Vec<TraitAlias<'hir>>,
crate is_crate: bool,
}
impl Module<'hir> {
crate fn new(
name: Option<Symbol>,
attrs: &'hir [ast::Attribute],
vis: &'hir hir::Visibility<'hir>,
) -> Module<'hir> {
crate fn new(name: Option<Symbol>, attrs: &'hir [ast::Attribute]) -> Module<'hir> {
Module {
name,
id: hir::CRATE_HIR_ID,
vis,
where_outer: rustc_span::DUMMY_SP,
where_inner: rustc_span::DUMMY_SP,
attrs,
@ -83,53 +77,39 @@ crate enum StructType {
}
crate struct Struct<'hir> {
crate vis: &'hir hir::Visibility<'hir>,
crate id: hir::HirId,
crate struct_type: StructType,
crate name: Symbol,
crate generics: &'hir hir::Generics<'hir>,
crate attrs: &'hir [ast::Attribute],
crate fields: &'hir [hir::StructField<'hir>],
crate span: Span,
}
crate struct Union<'hir> {
crate vis: &'hir hir::Visibility<'hir>,
crate id: hir::HirId,
crate struct_type: StructType,
crate name: Symbol,
crate generics: &'hir hir::Generics<'hir>,
crate attrs: &'hir [ast::Attribute],
crate fields: &'hir [hir::StructField<'hir>],
crate span: Span,
}
crate struct Enum<'hir> {
crate vis: &'hir hir::Visibility<'hir>,
crate variants: Vec<Variant<'hir>>,
crate generics: &'hir hir::Generics<'hir>,
crate attrs: &'hir [ast::Attribute],
crate id: hir::HirId,
crate span: Span,
crate name: Symbol,
}
crate struct Variant<'hir> {
crate name: Symbol,
crate id: hir::HirId,
crate attrs: &'hir [ast::Attribute],
crate def: &'hir hir::VariantData<'hir>,
crate span: Span,
}
crate struct Function<'hir> {
crate decl: &'hir hir::FnDecl<'hir>,
crate attrs: &'hir [ast::Attribute],
crate id: hir::HirId,
crate name: Symbol,
crate vis: &'hir hir::Visibility<'hir>,
crate header: hir::FnHeader,
crate span: Span,
crate generics: &'hir hir::Generics<'hir>,
crate body: hir::BodyId,
}
@ -139,18 +119,12 @@ crate struct Typedef<'hir> {
crate gen: &'hir hir::Generics<'hir>,
crate name: Symbol,
crate id: hir::HirId,
crate attrs: &'hir [ast::Attribute],
crate span: Span,
crate vis: &'hir hir::Visibility<'hir>,
}
crate struct OpaqueTy<'hir> {
crate opaque_ty: &'hir hir::OpaqueTy<'hir>,
crate name: Symbol,
crate id: hir::HirId,
crate attrs: &'hir [ast::Attribute],
crate span: Span,
crate vis: &'hir hir::Visibility<'hir>,
}
#[derive(Debug)]
@ -169,10 +143,7 @@ crate struct Constant<'hir> {
crate type_: &'hir hir::Ty<'hir>,
crate expr: hir::BodyId,
crate name: Symbol,
crate attrs: &'hir [ast::Attribute],
crate vis: &'hir hir::Visibility<'hir>,
crate id: hir::HirId,
crate span: Span,
}
crate struct Trait<'hir> {
@ -184,18 +155,13 @@ crate struct Trait<'hir> {
crate bounds: &'hir [hir::GenericBound<'hir>],
crate attrs: &'hir [ast::Attribute],
crate id: hir::HirId,
crate span: Span,
crate vis: &'hir hir::Visibility<'hir>,
}
crate struct TraitAlias<'hir> {
crate name: Symbol,
crate generics: &'hir hir::Generics<'hir>,
crate bounds: &'hir [hir::GenericBound<'hir>],
crate attrs: &'hir [ast::Attribute],
crate id: hir::HirId,
crate span: Span,
crate vis: &'hir hir::Visibility<'hir>,
}
#[derive(Debug)]
@ -215,22 +181,16 @@ crate struct Impl<'hir> {
}
crate struct ForeignItem<'hir> {
crate vis: &'hir hir::Visibility<'hir>,
crate id: hir::HirId,
crate name: Symbol,
crate kind: &'hir hir::ForeignItemKind<'hir>,
crate attrs: &'hir [ast::Attribute],
crate span: Span,
}
// For Macro we store the DefId instead of the NodeId, since we also create
// these imported macro_rules (which only have a DUMMY_NODE_ID).
crate struct Macro<'hir> {
crate struct Macro {
crate name: Symbol,
crate hid: hir::HirId,
crate def_id: hir::def_id::DefId,
crate attrs: &'hir [ast::Attribute],
crate span: Span,
crate matchers: Vec<Span>,
crate imported_from: Option<Symbol>,
}
@ -256,13 +216,11 @@ crate struct Import<'hir> {
crate span: Span,
}
crate struct ProcMacro<'hir> {
crate struct ProcMacro {
crate name: Symbol,
crate id: hir::HirId,
crate kind: MacroKind,
crate helpers: Vec<Symbol>,
crate attrs: &'hir [ast::Attribute],
crate span: Span,
}
crate fn struct_type_from_def(vdata: &hir::VariantData<'_>) -> StructType {

View File

@ -11,7 +11,7 @@ use std::fmt;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_span::def_id::DefId;
use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
use rustc_target::spec::abi::Abi;
use crate::clean::{self, PrimitiveType};
@ -1089,19 +1089,31 @@ impl Function<'_> {
impl clean::Visibility {
crate fn print_with_space(&self) -> impl fmt::Display + '_ {
use rustc_span::symbol::kw;
display_fn(move |f| match *self {
clean::Public => f.write_str("pub "),
clean::Inherited => Ok(()),
clean::Visibility::Crate => write!(f, "pub(crate) "),
// If this is `pub(crate)`, `path` will be empty.
clean::Visibility::Restricted(did, _) if did.index == CRATE_DEF_INDEX => {
write!(f, "pub(crate) ")
}
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")
debug!("path={:?}", path);
let first_name =
path.data[0].data.get_opt_name().expect("modules are always named");
if path.data.len() != 1 || (first_name != kw::SelfLower && first_name != kw::Super)
{
f.write_str("in ")?;
}
resolved_path(f, did, path, true, false)?;
f.write_str(") ")
// modified from `resolved_path()` to work with `DefPathData`
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
for seg in &path.data[..path.data.len() - 1] {
write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
}
let path = anchor(did, &last_name.as_str()).to_string();
write!(f, "{}) ", path)
}
})
}

View File

@ -50,13 +50,13 @@ impl<'a> DocFolder for Stripper<'a> {
}
clean::StructFieldItem(..) => {
if i.visibility != clean::Public {
if !i.visibility.is_public() {
return StripItem(i).strip();
}
}
clean::ModuleItem(..) => {
if i.def_id.is_local() && i.visibility != clean::Public {
if i.def_id.is_local() && !i.visibility.is_public() {
debug!("Stripper: stripping module {:?}", i.name);
let old = mem::replace(&mut self.update_retained, false);
let ret = StripItem(self.fold_item_recur(i).unwrap()).strip();
@ -163,9 +163,7 @@ crate struct ImportStripper;
impl DocFolder for ImportStripper {
fn fold_item(&mut self, i: Item) -> Option<Item> {
match i.kind {
clean::ExternCrateItem(..) | clean::ImportItem(..) if i.visibility != clean::Public => {
None
}
clean::ExternCrateItem(..) | clean::ImportItem(..) if !i.visibility.is_public() => None,
_ => self.fold_item_recur(i),
}
}

View File

@ -91,16 +91,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
) -> Struct<'tcx> {
debug!("visiting struct");
let struct_type = struct_type_from_def(&*sd);
Struct {
id: item.hir_id,
struct_type,
name,
vis: &item.vis,
attrs: &item.attrs,
generics,
fields: sd.fields(),
span: item.span,
}
Struct { id: item.hir_id, struct_type, name, generics, fields: sd.fields() }
}
fn visit_union_data(
@ -112,16 +103,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
) -> Union<'tcx> {
debug!("visiting union");
let struct_type = struct_type_from_def(&*sd);
Union {
id: item.hir_id,
struct_type,
name,
vis: &item.vis,
attrs: &item.attrs,
generics,
fields: sd.fields(),
span: item.span,
}
Union { id: item.hir_id, struct_type, name, generics, fields: sd.fields() }
}
fn visit_enum_def(
@ -137,19 +119,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
variants: def
.variants
.iter()
.map(|v| Variant {
name: v.ident.name,
id: v.id,
attrs: &v.attrs,
def: &v.data,
span: v.span,
})
.map(|v| Variant { name: v.ident.name, id: v.id, def: &v.data })
.collect(),
vis: &it.vis,
generics,
attrs: &it.attrs,
id: it.hir_id,
span: it.span,
}
}
@ -202,27 +175,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
}
}
om.proc_macros.push(ProcMacro {
name,
id: item.hir_id,
kind,
helpers,
attrs: &item.attrs,
span: item.span,
});
om.proc_macros.push(ProcMacro { name, id: item.hir_id, kind, helpers });
}
None => {
om.fns.push(Function {
id: item.hir_id,
vis: &item.vis,
attrs: &item.attrs,
decl,
name,
span: item.span,
generics,
header,
body,
});
om.fns.push(Function { id: item.hir_id, decl, name, generics, header, body });
}
}
}
@ -236,7 +192,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
m: &'tcx hir::Mod<'tcx>,
name: Option<Symbol>,
) -> Module<'tcx> {
let mut om = Module::new(name, attrs, vis);
let mut om = Module::new(name, attrs);
om.where_outer = span;
om.where_inner = m.inner;
om.id = id;
@ -471,26 +427,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
self.visit_fn(om, item, ident.name, &sig.decl, sig.header, gen, body)
}
hir::ItemKind::TyAlias(ty, ref gen) => {
let t = Typedef {
ty,
gen,
name: ident.name,
id: item.hir_id,
attrs: &item.attrs,
span: item.span,
vis: &item.vis,
};
let t = Typedef { ty, gen, name: ident.name, id: item.hir_id };
om.typedefs.push(t);
}
hir::ItemKind::OpaqueTy(ref opaque_ty) => {
let t = OpaqueTy {
opaque_ty,
name: ident.name,
id: item.hir_id,
attrs: &item.attrs,
span: item.span,
vis: &item.vis,
};
let t = OpaqueTy { opaque_ty, name: ident.name, id: item.hir_id };
om.opaque_tys.push(t);
}
hir::ItemKind::Static(type_, mutability, expr) => {
@ -510,15 +451,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
// Underscore constants do not correspond to a nameable item and
// so are never useful in documentation.
if ident.name != kw::Underscore {
let s = Constant {
type_,
expr,
id: item.hir_id,
name: ident.name,
attrs: &item.attrs,
span: item.span,
vis: &item.vis,
};
let s = Constant { type_, expr, id: item.hir_id, name: ident.name };
om.constants.push(s);
}
}
@ -533,21 +466,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
bounds,
id: item.hir_id,
attrs: &item.attrs,
span: item.span,
vis: &item.vis,
};
om.traits.push(t);
}
hir::ItemKind::TraitAlias(ref generics, ref bounds) => {
let t = TraitAlias {
name: ident.name,
generics,
bounds,
id: item.hir_id,
attrs: &item.attrs,
span: item.span,
vis: &item.vis,
};
let t = TraitAlias { name: ident.name, generics, bounds, id: item.hir_id };
om.trait_aliases.push(t);
}
@ -602,29 +525,19 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
id: item.hir_id,
name: renamed.unwrap_or(item.ident).name,
kind: &item.kind,
vis: &item.vis,
attrs: &item.attrs,
span: item.span,
});
}
// Convert each `exported_macro` into a doc item.
fn visit_local_macro(
&self,
def: &'tcx hir::MacroDef<'_>,
renamed: Option<Symbol>,
) -> Macro<'tcx> {
fn visit_local_macro(&self, def: &'tcx hir::MacroDef<'_>, renamed: Option<Symbol>) -> Macro {
debug!("visit_local_macro: {}", def.ident);
let tts = def.ast.body.inner_tokens().trees().collect::<Vec<_>>();
// Extract the spans of all matchers. They represent the "interface" of the macro.
let matchers = tts.chunks(4).map(|arm| arm[0].span()).collect();
Macro {
hid: def.hir_id,
def_id: self.cx.tcx.hir().local_def_id(def.hir_id).to_def_id(),
attrs: &def.attrs,
name: renamed.unwrap_or(def.ident.name),
span: def.span,
matchers,
imported_from: None,
}

View File

@ -4,10 +4,12 @@
// @has variant_struct/enum.Foo.html
// @!has - 'pub qux'
// @!has - 'pub(crate) qux'
// @!has - 'pub Bar'
extern crate variant_struct;
// @has issue_32395/enum.Foo.html
// @!has - 'pub qux'
// @!has - 'pub(crate) qux'
// @!has - 'pub Bar'
pub use variant_struct::Foo;

View File

@ -1,5 +1,3 @@
// ignore-tidy-linelength
// compile-flags: --document-private-items
#![feature(crate_visibility_modifier)]
@ -12,21 +10,21 @@ pub struct FooPublic;
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'
// @has 'foo/struct.FooSelf.html' '//pre' 'pub(crate) struct FooSelf'
pub(self) struct FooSelf;
// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(self) struct FooInSelf'
// @has 'foo/struct.FooInSelf.html' '//pre' 'pub(crate) struct FooInSelf'
pub(in self) struct FooInSelf;
mod a {
// @has 'foo/a/struct.FooSuper.html' '//pre' 'pub(super) struct FooSuper'
// @has 'foo/a/struct.FooSuper.html' '//pre' 'pub(crate) struct FooSuper'
pub(super) struct FooSuper;
// @has 'foo/a/struct.FooInSuper.html' '//pre' 'pub(super) struct FooInSuper'
// @has 'foo/a/struct.FooInSuper.html' '//pre' 'pub(crate) 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'
// @has 'foo/a/b/struct.FooInSelfSuperB.html' '//pre' 'pub(in a::b) struct FooInSelfSuperB'
pub(in a::b) struct FooInSelfSuperB;
// @has 'foo/a/b/struct.FooInSuperSuper.html' '//pre' 'pub(crate) 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;