Display #[non_exhaustive] in rustdoc on types.
This commit is contained in:
parent
ed0350e945
commit
a074bd7334
8 changed files with 75 additions and 3 deletions
|
@ -229,6 +229,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
|
|||
def_id: self.next_def_id(def_id.krate),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
non_exhaustive: false,
|
||||
inner: ImplItem(Impl {
|
||||
unsafety: hir::Unsafety::Normal,
|
||||
generics: new_generics,
|
||||
|
|
|
@ -111,6 +111,7 @@ pub fn try_inline(cx: &DocContext, def: Def, name: ast::Name, visited: &mut FxHa
|
|||
visibility: Some(clean::Public),
|
||||
stability: cx.tcx.lookup_stability(did).clean(cx),
|
||||
deprecation: cx.tcx.lookup_deprecation(did).clean(cx),
|
||||
non_exhaustive: false,
|
||||
def_id: did,
|
||||
});
|
||||
Some(ret)
|
||||
|
@ -412,6 +413,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
|
|||
visibility: Some(clean::Inherited),
|
||||
stability: tcx.lookup_stability(did).clean(cx),
|
||||
deprecation: tcx.lookup_deprecation(did).clean(cx),
|
||||
non_exhaustive: false,
|
||||
def_id: did,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -192,6 +192,7 @@ impl<'a, 'tcx, 'rcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx, 'rcx>
|
|||
visibility: Some(Public),
|
||||
stability: get_stability(cx, def_id),
|
||||
deprecation: get_deprecation(cx, def_id),
|
||||
non_exhaustive: false,
|
||||
def_id,
|
||||
inner: PrimitiveItem(prim),
|
||||
}
|
||||
|
@ -204,6 +205,7 @@ impl<'a, 'tcx, 'rcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx, 'rcx>
|
|||
visibility: Some(Public),
|
||||
stability: get_stability(cx, def_id),
|
||||
deprecation: get_deprecation(cx, def_id),
|
||||
non_exhaustive: false,
|
||||
def_id,
|
||||
inner: KeywordItem(kw),
|
||||
}
|
||||
|
@ -366,6 +368,7 @@ pub struct Item {
|
|||
pub def_id: DefId,
|
||||
pub stability: Option<Stability>,
|
||||
pub deprecation: Option<Deprecation>,
|
||||
pub non_exhaustive: bool,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Item {
|
||||
|
@ -625,6 +628,7 @@ impl Clean<Item> for doctree::Module {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
def_id: cx.tcx.hir.local_def_id(self.id),
|
||||
inner: ModuleItem(Module {
|
||||
is_crate: self.is_crate,
|
||||
|
@ -2117,6 +2121,7 @@ impl Clean<Item> for doctree::Function {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
def_id: cx.tcx.hir.local_def_id(self.id),
|
||||
inner: FunctionItem(Function {
|
||||
decl,
|
||||
|
@ -2298,6 +2303,7 @@ impl Clean<Item> for doctree::Trait {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
inner: TraitItem(Trait {
|
||||
auto: self.is_auto.clean(cx),
|
||||
unsafety: self.unsafety,
|
||||
|
@ -2367,6 +2373,7 @@ impl Clean<Item> for hir::TraitItem {
|
|||
visibility: None,
|
||||
stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
|
||||
deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
|
||||
non_exhaustive: false,
|
||||
inner,
|
||||
}
|
||||
}
|
||||
|
@ -2395,6 +2402,7 @@ impl Clean<Item> for hir::ImplItem {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
|
||||
deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
|
||||
non_exhaustive: false,
|
||||
inner,
|
||||
}
|
||||
}
|
||||
|
@ -2541,6 +2549,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
|||
visibility,
|
||||
stability: get_stability(cx, self.def_id),
|
||||
deprecation: get_deprecation(cx, self.def_id),
|
||||
non_exhaustive: false,
|
||||
def_id: self.def_id,
|
||||
attrs: inline::load_attrs(cx, self.def_id),
|
||||
source: cx.tcx.def_span(self.def_id).clean(cx),
|
||||
|
@ -3194,6 +3203,7 @@ impl Clean<Item> for hir::StructField {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
|
||||
deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
|
||||
non_exhaustive: false,
|
||||
def_id: cx.tcx.hir.local_def_id(self.id),
|
||||
inner: StructFieldItem(self.ty.clean(cx)),
|
||||
}
|
||||
|
@ -3209,6 +3219,7 @@ impl<'tcx> Clean<Item> for ty::FieldDef {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: get_stability(cx, self.did),
|
||||
deprecation: get_deprecation(cx, self.did),
|
||||
non_exhaustive: false,
|
||||
def_id: self.did,
|
||||
inner: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)),
|
||||
}
|
||||
|
@ -3273,6 +3284,7 @@ impl Clean<Vec<Item>> for doctree::Struct {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: self.non_exhaustive,
|
||||
inner: StructItem(Struct {
|
||||
struct_type: self.struct_type,
|
||||
generics: self.generics.clean(cx),
|
||||
|
@ -3298,6 +3310,7 @@ impl Clean<Vec<Item>> for doctree::Union {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
inner: UnionItem(Union {
|
||||
struct_type: self.struct_type,
|
||||
generics: self.generics.clean(cx),
|
||||
|
@ -3350,6 +3363,7 @@ impl Clean<Vec<Item>> for doctree::Enum {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: self.non_exhaustive,
|
||||
inner: EnumItem(Enum {
|
||||
variants: self.variants.clean(cx),
|
||||
generics: self.generics.clean(cx),
|
||||
|
@ -3375,6 +3389,7 @@ impl Clean<Item> for doctree::Variant {
|
|||
visibility: None,
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
def_id: cx.tcx.hir.local_def_id(self.def.id()),
|
||||
inner: VariantItem(Variant {
|
||||
kind: self.def.clean(cx),
|
||||
|
@ -3405,6 +3420,7 @@ impl<'tcx> Clean<Item> for ty::VariantDef {
|
|||
def_id: field.did,
|
||||
stability: get_stability(cx, field.did),
|
||||
deprecation: get_deprecation(cx, field.did),
|
||||
non_exhaustive: false,
|
||||
inner: StructFieldItem(cx.tcx.type_of(field.did).clean(cx))
|
||||
}
|
||||
}).collect()
|
||||
|
@ -3420,6 +3436,7 @@ impl<'tcx> Clean<Item> for ty::VariantDef {
|
|||
inner: VariantItem(Variant { kind: kind }),
|
||||
stability: get_stability(cx, self.did),
|
||||
deprecation: get_deprecation(cx, self.did),
|
||||
non_exhaustive: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3671,6 +3688,7 @@ impl Clean<Item> for doctree::Typedef {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
inner: TypedefItem(Typedef {
|
||||
type_: self.ty.clean(cx),
|
||||
generics: self.gen.clean(cx),
|
||||
|
@ -3722,6 +3740,7 @@ impl Clean<Item> for doctree::Static {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
inner: StaticItem(Static {
|
||||
type_: self.type_.clean(cx),
|
||||
mutability: self.mutability.clean(cx),
|
||||
|
@ -3747,6 +3766,7 @@ impl Clean<Item> for doctree::Constant {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
inner: ConstantItem(Constant {
|
||||
type_: self.type_.clean(cx),
|
||||
expr: print_const_expr(cx, self.expr),
|
||||
|
@ -3835,6 +3855,7 @@ impl Clean<Vec<Item>> for doctree::Impl {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
inner: ImplItem(Impl {
|
||||
unsafety: self.unsafety,
|
||||
generics: self.generics.clean(cx),
|
||||
|
@ -3921,6 +3942,7 @@ impl Clean<Item> for doctree::ExternCrate {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
non_exhaustive: false,
|
||||
inner: ExternCrateItem(self.name.clean(cx), self.path.clone())
|
||||
}
|
||||
}
|
||||
|
@ -3967,6 +3989,7 @@ impl Clean<Vec<Item>> for doctree::Import {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: None,
|
||||
deprecation: None,
|
||||
non_exhaustive: false,
|
||||
inner: ImportItem(inner)
|
||||
}]
|
||||
}
|
||||
|
@ -4035,6 +4058,7 @@ impl Clean<Item> for hir::ForeignItem {
|
|||
visibility: self.vis.clean(cx),
|
||||
stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
|
||||
deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
|
||||
non_exhaustive: false,
|
||||
inner,
|
||||
}
|
||||
}
|
||||
|
@ -4209,6 +4233,7 @@ impl Clean<Item> for doctree::Macro {
|
|||
visibility: Some(Public),
|
||||
stability: self.stab.clean(cx),
|
||||
deprecation: self.depr.clean(cx),
|
||||
non_exhaustive: false,
|
||||
def_id: self.def_id,
|
||||
inner: MacroItem(Macro {
|
||||
source: format!("macro_rules! {} {{\n{}}}",
|
||||
|
|
|
@ -97,6 +97,7 @@ pub struct Struct {
|
|||
pub vis: hir::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub depr: Option<attr::Deprecation>,
|
||||
pub non_exhaustive: bool,
|
||||
pub id: NodeId,
|
||||
pub struct_type: StructType,
|
||||
pub name: Name,
|
||||
|
@ -123,6 +124,7 @@ pub struct Enum {
|
|||
pub vis: hir::Visibility,
|
||||
pub stab: Option<attr::Stability>,
|
||||
pub depr: Option<attr::Deprecation>,
|
||||
pub non_exhaustive: bool,
|
||||
pub variants: hir::HirVec<Variant>,
|
||||
pub generics: hir::Generics,
|
||||
pub attrs: hir::HirVec<ast::Attribute>,
|
||||
|
|
|
@ -90,7 +90,17 @@ pub trait DocFolder : Sized {
|
|||
|
||||
/// don't override!
|
||||
fn fold_item_recur(&mut self, item: Item) -> Option<Item> {
|
||||
let Item { attrs, name, source, visibility, def_id, inner, stability, deprecation } = item;
|
||||
let Item {
|
||||
attrs,
|
||||
name,
|
||||
source,
|
||||
visibility,
|
||||
def_id,
|
||||
inner,
|
||||
stability,
|
||||
deprecation,
|
||||
non_exhaustive
|
||||
} = item;
|
||||
|
||||
let inner = match inner {
|
||||
StrippedItem(box i) => StrippedItem(box self.fold_inner_recur(i)),
|
||||
|
@ -98,7 +108,7 @@ pub trait DocFolder : Sized {
|
|||
};
|
||||
|
||||
Some(Item { attrs, name, source, inner, visibility,
|
||||
stability, deprecation, def_id })
|
||||
stability, deprecation, non_exhaustive, def_id })
|
||||
}
|
||||
|
||||
fn fold_mod(&mut self, m: Module) -> Module {
|
||||
|
|
|
@ -2194,6 +2194,7 @@ fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Re
|
|||
info!("Documenting {}", name);
|
||||
}
|
||||
document_stability(w, cx, item)?;
|
||||
document_non_exhaustive(w, item)?;
|
||||
let prefix = render_assoc_const_value(item);
|
||||
document_full(w, item, cx, &prefix)?;
|
||||
Ok(())
|
||||
|
@ -2262,6 +2263,28 @@ fn document_stability(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item)
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn document_non_exhaustive(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
|
||||
if item.non_exhaustive {
|
||||
write!(w, r##"
|
||||
<div class='non-exhaustive'>
|
||||
<div class='stab non-exhaustive'>
|
||||
<details>
|
||||
<summary>
|
||||
<span class=microscope>🔬</span>
|
||||
This type is marked as non exhaustive.
|
||||
</summary>
|
||||
<p>
|
||||
This type will require a wildcard arm in any match statements or constructors.
|
||||
</p>
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
"##)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn name_key(name: &str) -> (&str, u64, usize) {
|
||||
// find number at end
|
||||
let split = name.bytes().rposition(|b| b < b'0' || b'9' < b).map_or(0, |s| s + 1);
|
||||
|
|
|
@ -188,6 +188,7 @@ a.test-arrow {
|
|||
border-color: #66afe9;
|
||||
}
|
||||
|
||||
.stab.non-exhaustive { background: #F5F5F5; border-color: #D3D3D3; }
|
||||
.stab.unstable { background: #FFF5D6; border-color: #FFC600; }
|
||||
.stab.deprecated { background: #F3DFFF; border-color: #7F0087; }
|
||||
.stab.portability { background: #C4ECFF; border-color: #7BA5DB; }
|
||||
|
|
|
@ -89,6 +89,12 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
|
|||
.and_then(|def_id| self.cx.tcx.lookup_deprecation(def_id))
|
||||
}
|
||||
|
||||
fn non_exhaustive(&self, id: ast::NodeId) -> bool {
|
||||
self.cx.tcx.hir.opt_local_def_id(id)
|
||||
.map(|def_id| self.cx.tcx.has_attr(def_id, "non_exhaustive"))
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn visit(&mut self, krate: &hir::Crate) {
|
||||
self.attrs = krate.attrs.clone();
|
||||
|
||||
|
@ -119,6 +125,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
|
|||
vis: item.vis.clone(),
|
||||
stab: self.stability(item.id),
|
||||
depr: self.deprecation(item.id),
|
||||
non_exhaustive: self.non_exhaustive(item.id),
|
||||
attrs: item.attrs.clone(),
|
||||
generics: generics.clone(),
|
||||
fields: sd.fields().iter().cloned().collect(),
|
||||
|
@ -162,6 +169,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
|
|||
vis: it.vis.clone(),
|
||||
stab: self.stability(it.id),
|
||||
depr: self.deprecation(it.id),
|
||||
non_exhaustive: self.non_exhaustive(it.id),
|
||||
generics: params.clone(),
|
||||
attrs: it.attrs.clone(),
|
||||
id: it.id,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue