From 541ad45a83482e3132c75fbbc55fb2afc03a6031 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 5 Mar 2019 02:29:21 +0100 Subject: [PATCH] Add default keyword handling in rustdoc --- src/librustdoc/clean/mod.rs | 24 ++++++++++++++++++++---- src/librustdoc/html/format.rs | 11 +++++++++++ src/librustdoc/html/render.rs | 8 +++++--- src/test/rustdoc/default_trait_method.rs | 15 +++++++++++++++ 4 files changed, 51 insertions(+), 7 deletions(-) create mode 100644 src/test/rustdoc/default_trait_method.rs diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f2bf7ead5619b..86958e06d5c5b 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -507,6 +507,18 @@ impl Item { .as_ref() .or_else(|| self.stability.as_ref().and_then(|s| s.deprecation.as_ref())) } + pub fn is_default(&self) -> bool { + match self.inner { + ItemEnum::MethodItem(ref meth) => { + if let Some(defaultness) = meth.defaultness { + defaultness.has_value() && !defaultness.is_final() + } else { + false + } + } + _ => false, + } + } } #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] @@ -1699,9 +1711,11 @@ pub struct Method { pub generics: Generics, pub decl: FnDecl, pub header: hir::FnHeader, + pub defaultness: Option, } -impl<'a> Clean for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) { +impl<'a> Clean for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId, + Option) { fn clean(&self, cx: &DocContext<'_>) -> Method { let (generics, decl) = enter_impl_trait(cx, || { (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)) @@ -1710,6 +1724,7 @@ impl<'a> Clean for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) decl, generics, header: self.0.header, + defaultness: self.3, } } } @@ -2015,7 +2030,7 @@ impl Clean for hir::TraitItem { default.map(|e| print_const_expr(cx, e))) } hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => { - MethodItem((sig, &self.generics, body).clean(cx)) + MethodItem((sig, &self.generics, body, None).clean(cx)) } hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => { let (generics, decl) = enter_impl_trait(cx, || { @@ -2053,7 +2068,7 @@ impl Clean for hir::ImplItem { Some(print_const_expr(cx, expr))) } hir::ImplItemKind::Method(ref sig, body) => { - MethodItem((sig, &self.generics, body).clean(cx)) + MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx)) } hir::ImplItemKind::Type(ref ty) => TypedefItem(Typedef { type_: ty.clean(cx), @@ -2136,7 +2151,8 @@ impl<'tcx> Clean for ty::AssociatedItem { abi: sig.abi(), constness, asyncness: hir::IsAsync::NotAsync, - } + }, + defaultness: Some(self.defaultness), }) } else { TyMethodItem(TyMethod { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index d204a179ca62c..48baf27bae20a 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -45,6 +45,7 @@ pub struct GenericBounds<'a>(pub &'a [clean::GenericBound]); /// Wrapper struct for emitting a comma-separated list of items pub struct CommaSep<'a, T>(pub &'a [T]); pub struct AbiSpace(pub Abi); +pub struct DefaultSpace(pub bool); /// Wrapper struct for properly emitting a function or method declaration. pub struct Function<'a> { @@ -1057,3 +1058,13 @@ impl fmt::Display for AbiSpace { } } } + +impl fmt::Display for DefaultSpace { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + if self.0 { + write!(f, "default ") + } else { + Ok(()) + } + } +} diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d711e4514a049..f02e4a01ec56c 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -61,7 +61,7 @@ use crate::doctree; use crate::fold::DocFolder; use crate::html::escape::Escape; use crate::html::format::{AsyncSpace, ConstnessSpace}; -use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace}; +use crate::html::format::{GenericBounds, WhereClause, href, AbiSpace, DefaultSpace}; use crate::html::format::{VisSpace, Function, UnsafetySpace, MutableSpace}; use crate::html::format::fmt_impl_for_trait_page; use crate::html::item_type::ItemType; @@ -3434,11 +3434,12 @@ fn render_assoc_item(w: &mut fmt::Formatter<'_>, } }; let mut header_len = format!( - "{}{}{}{}{:#}fn {}{:#}", + "{}{}{}{}{}{:#}fn {}{:#}", VisSpace(&meth.visibility), ConstnessSpace(header.constness), UnsafetySpace(header.unsafety), AsyncSpace(header.asyncness), + DefaultSpace(meth.is_default()), AbiSpace(header.abi), name, *g @@ -3450,12 +3451,13 @@ fn render_assoc_item(w: &mut fmt::Formatter<'_>, (0, true) }; render_attributes(w, meth)?; - write!(w, "{}{}{}{}{}fn {name}\ + write!(w, "{}{}{}{}{}{}fn {name}\ {generics}{decl}{where_clause}", VisSpace(&meth.visibility), ConstnessSpace(header.constness), UnsafetySpace(header.unsafety), AsyncSpace(header.asyncness), + DefaultSpace(meth.is_default()), AbiSpace(header.abi), href = href, name = name, diff --git a/src/test/rustdoc/default_trait_method.rs b/src/test/rustdoc/default_trait_method.rs new file mode 100644 index 0000000000000..dfbd8f2210fa4 --- /dev/null +++ b/src/test/rustdoc/default_trait_method.rs @@ -0,0 +1,15 @@ +#![feature(specialization)] + +pub trait Item { + fn foo(); + fn bar(); +} + +// @has default_trait_method/trait.Item.html +// @has - '//*[@id="method.foo"]' 'default fn foo()' +// @has - '//*[@id="method.bar"]' 'fn bar()' +// @!has - '//*[@id="method.bar"]' 'default fn bar()' +impl Item for T { + default fn foo() {} + fn bar() {} +}