* Visibility was missing from impl items.
* Attributes and docs were missing from consts and types in impls.
* Const default values were missing from traits.
This unifies the code that handles associated items from impls and traits.
let predicates = tcx.predicates_of(did);
let trait_items = tcx.associated_items(did).filter_map(|item| {
- match item.kind {
- ty::AssociatedKind::Const => {
- let default = if item.defaultness.has_value() {
- Some(print_inlined_const(cx, item.def_id))
- } else {
- None
- };
- Some(clean::Item {
- name: Some(item.name.clean(cx)),
- inner: clean::AssociatedConstItem(
- tcx.type_of(item.def_id).clean(cx),
- default,
- ),
- source: tcx.def_span(item.def_id).clean(cx),
- attrs: clean::Attributes::default(),
- visibility: None,
- stability: tcx.lookup_stability(item.def_id).clean(cx),
- deprecation: tcx.lookup_deprecation(item.def_id).clean(cx),
- def_id: item.def_id
- })
- }
- ty::AssociatedKind::Method => {
- if item.vis != ty::Visibility::Public && associated_trait.is_none() {
- return None
- }
- let mut cleaned = item.clean(cx);
- cleaned.inner = match cleaned.inner.clone() {
- clean::TyMethodItem(clean::TyMethod {
- unsafety, decl, generics, abi
- }) => {
- let constness = if tcx.is_const_fn(item.def_id) {
- hir::Constness::Const
- } else {
- hir::Constness::NotConst
- };
-
- clean::MethodItem(clean::Method {
- unsafety,
- constness,
- decl,
- generics,
- abi,
- })
- }
- ref r => panic!("not a tymethod: {:?}", r),
- };
- Some(cleaned)
- }
- ty::AssociatedKind::Type => {
- let typedef = clean::Typedef {
- type_: tcx.type_of(item.def_id).clean(cx),
- generics: clean::Generics {
- lifetimes: vec![],
- type_params: vec![],
- where_predicates: vec![]
- }
- };
- Some(clean::Item {
- name: Some(item.name.clean(cx)),
- inner: clean::TypedefItem(typedef, true),
- source: tcx.def_span(item.def_id).clean(cx),
- attrs: clean::Attributes::default(),
- visibility: None,
- stability: tcx.lookup_stability(item.def_id).clean(cx),
- deprecation: tcx.lookup_deprecation(item.def_id).clean(cx),
- def_id: item.def_id
- })
- }
+ if associated_trait.is_some() || item.vis == ty::Visibility::Public {
+ Some(item.clean(cx))
+ } else {
+ None
}
}).collect::<Vec<_>>();
let polarity = tcx.impl_polarity(did);
let inner = match self.kind {
ty::AssociatedKind::Const => {
let ty = cx.tcx.type_of(self.def_id);
- AssociatedConstItem(ty.clean(cx), None)
+ let default = if self.defaultness.has_value() {
+ Some(inline::print_inlined_const(cx, self.def_id))
+ } else {
+ None
+ };
+ AssociatedConstItem(ty.clean(cx), default)
}
ty::AssociatedKind::Method => {
let generics = (cx.tcx.generics_of(self.def_id),
}
let provided = match self.container {
- ty::ImplContainer(_) => false,
+ ty::ImplContainer(_) => true,
ty::TraitContainer(_) => self.defaultness.has_value()
};
if provided {
+ let constness = if cx.tcx.is_const_fn(self.def_id) {
+ hir::Constness::Const
+ } else {
+ hir::Constness::NotConst
+ };
MethodItem(Method {
unsafety: sig.unsafety(),
generics,
decl,
abi: sig.abi(),
-
- // trait methods cannot (currently, at least) be const
- constness: hir::Constness::NotConst,
+ constness,
})
} else {
TyMethodItem(TyMethod {
ty::AssociatedKind::Type => {
let my_name = self.name.clean(cx);
- let mut bounds = if let ty::TraitContainer(did) = self.container {
+ if let ty::TraitContainer(did) = self.container {
// When loading a cross-crate associated type, the bounds for this type
// are actually located on the trait/impl itself, so we need to load
// all of the generics from there and then look for bounds that are
// applied to this associated type in question.
let predicates = cx.tcx.predicates_of(did);
let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
- generics.where_predicates.iter().filter_map(|pred| {
+ let mut bounds = generics.where_predicates.iter().filter_map(|pred| {
let (name, self_type, trait_, bounds) = match *pred {
WherePredicate::BoundPredicate {
ty: QPath { ref name, ref self_type, ref trait_ },
_ => return None,
}
Some(bounds)
- }).flat_map(|i| i.iter().cloned()).collect::<Vec<_>>()
- } else {
- vec![]
- };
+ }).flat_map(|i| i.iter().cloned()).collect::<Vec<_>>();
+ // Our Sized/?Sized bound didn't get handled when creating the generics
+ // because we didn't actually get our whole set of bounds until just now
+ // (some of them may have come from the trait). If we do have a sized
+ // bound, we remove it, and if we don't then we add the `?Sized` bound
+ // at the end.
+ match bounds.iter().position(|b| b.is_sized_bound(cx)) {
+ Some(i) => { bounds.remove(i); }
+ None => bounds.push(TyParamBound::maybe_sized(cx)),
+ }
- // Our Sized/?Sized bound didn't get handled when creating the generics
- // because we didn't actually get our whole set of bounds until just now
- // (some of them may have come from the trait). If we do have a sized
- // bound, we remove it, and if we don't then we add the `?Sized` bound
- // at the end.
- match bounds.iter().position(|b| b.is_sized_bound(cx)) {
- Some(i) => { bounds.remove(i); }
- None => bounds.push(TyParamBound::maybe_sized(cx)),
- }
+ let ty = if self.defaultness.has_value() {
+ Some(cx.tcx.type_of(self.def_id))
+ } else {
+ None
+ };
- let ty = if self.defaultness.has_value() {
- Some(cx.tcx.type_of(self.def_id))
+ AssociatedTypeItem(bounds, ty.clean(cx))
} else {
- None
- };
-
- AssociatedTypeItem(bounds, ty.clean(cx))
+ TypedefItem(Typedef {
+ type_: cx.tcx.type_of(self.def_id).clean(cx),
+ generics: Generics {
+ lifetimes: Vec::new(),
+ type_params: Vec::new(),
+ where_predicates: Vec::new(),
+ },
+ }, true)
+ }
}
};
+ let visibility = match self.container {
+ ty::ImplContainer(_) => self.vis.clean(cx),
+ ty::TraitContainer(_) => None,
+ };
+
Item {
name: Some(self.name.clean(cx)),
- visibility: Some(Inherited),
+ visibility,
stability: get_stability(cx, self.def_id),
deprecation: get_deprecation(cx, self.def_id),
def_id: self.def_id,
ty: &clean::Type,
_default: Option<&String>,
link: AssocItemLink) -> fmt::Result {
- write!(w, "const <a href='{}' class=\"constant\"><b>{}</b></a>: {}",
+ write!(w, "{}const <a href='{}' class=\"constant\"><b>{}</b></a>: {}",
+ VisSpace(&it.visibility),
naive_assoc_href(it, link),
it.name.as_ref().unwrap(),
ty)?;
--- /dev/null
+// Copyright 2017 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:assoc-items.rs
+// build-aux-docs
+// ignore-cross-compile
+
+#![crate_name = "foo"]
+
+extern crate assoc_items;
+
+// @has foo/struct.MyStruct.html
+// @!has - 'PrivateConst'
+// @has - '//*[@id="associatedconstant.PublicConst"]' 'pub const PublicConst: u8'
+// @has - '//*[@class="docblock"]' 'PublicConst: u8 = 123'
+// @has - '//*[@class="docblock"]' 'docs for PublicConst'
+// @!has - 'private_method'
+// @has - '//*[@id="method.public_method"]' 'pub fn public_method()'
+// @has - '//*[@class="docblock"]' 'docs for public_method'
+// @has - '//*[@id="associatedconstant.ConstNoDefault"]' 'const ConstNoDefault: i16'
+// @has - '//*[@class="docblock"]' 'ConstNoDefault: i16 = -123'
+// @has - '//*[@class="docblock"]' 'dox for ConstNoDefault'
+// @has - '//*[@id="associatedconstant.ConstWithDefault"]' 'const ConstWithDefault: u16'
+// @has - '//*[@class="docblock"]' 'ConstWithDefault: u16 = 12345'
+// @has - '//*[@class="docblock"]' 'docs for ConstWithDefault'
+// @has - '//*[@id="associatedtype.TypeNoDefault"]' 'type TypeNoDefault = i32'
+// @has - '//*[@class="docblock"]' 'dox for TypeNoDefault'
+// @has - '//*[@id="associatedtype.TypeWithDefault"]' 'type TypeWithDefault = u32'
+// @has - '//*[@class="docblock"]' 'docs for TypeWithDefault'
+// @has - '//*[@id="method.method_no_default"]' 'fn method_no_default()'
+// @has - '//*[@class="docblock"]' 'dox for method_no_default'
+// @has - '//*[@id="method.method_with_default"]' 'fn method_with_default()'
+// @has - '//*[@class="docblock"]' 'docs for method_with_default'
+pub use assoc_items::MyStruct;
+
+// @has foo/trait.MyTrait.html
+// @has - '//*[@id="associatedconstant.ConstNoDefault"]' 'const ConstNoDefault: i16'
+// @has - '//*[@class="docblock"]' 'docs for ConstNoDefault'
+// @has - '//*[@id="associatedconstant.ConstWithDefault"]' 'const ConstWithDefault: u16'
+// @has - '//*[@class="docblock"]' 'ConstWithDefault: u16 = 12345'
+// @has - '//*[@class="docblock"]' 'docs for ConstWithDefault'
+// @has - '//*[@id="associatedtype.TypeNoDefault"]' 'type TypeNoDefault'
+// @has - '//*[@class="docblock"]' 'docs for TypeNoDefault'
+// @has - '//*[@id="associatedtype.TypeWithDefault"]' 'type TypeWithDefault = u32'
+// @has - '//*[@class="docblock"]' 'docs for TypeWithDefault'
+// @has - '//*[@id="tymethod.method_no_default"]' 'fn method_no_default()'
+// @has - '//*[@class="docblock"]' 'docs for method_no_default'
+// @has - '//*[@id="method.method_with_default"]' 'fn method_with_default()'
+// @has - '//*[@class="docblock"]' 'docs for method_with_default'
+pub use assoc_items::MyTrait;
--- /dev/null
+// Copyright 2017 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(associated_type_defaults)]
+
+pub struct MyStruct;
+
+impl MyStruct {
+ /// docs for PrivateConst
+ const PrivateConst: i8 = -123;
+ /// docs for PublicConst
+ pub const PublicConst: u8 = 123;
+ /// docs for private_method
+ fn private_method() {}
+ /// docs for public_method
+ pub fn public_method() {}
+}
+
+pub trait MyTrait {
+ /// docs for ConstNoDefault
+ const ConstNoDefault: i16;
+ /// docs for ConstWithDefault
+ const ConstWithDefault: u16 = 12345;
+ /// docs for TypeNoDefault
+ type TypeNoDefault;
+ /// docs for TypeWithDefault
+ type TypeWithDefault = u32;
+ /// docs for method_no_default
+ fn method_no_default();
+ /// docs for method_with_default
+ fn method_with_default() {}
+}
+
+impl MyTrait for MyStruct {
+ /// dox for ConstNoDefault
+ const ConstNoDefault: i16 = -12345;
+ /// dox for TypeNoDefault
+ type TypeNoDefault = i32;
+ /// dox for method_no_default
+ fn method_no_default() {}
+}