Skip to content

Add trait alias support in rustdoc #58243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 32 additions & 4 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ pub enum ItemEnum {
StaticItem(Static),
ConstantItem(Constant),
TraitItem(Trait),
TraitAliasItem(TraitAlias),
ImplItem(Impl),
/// A method signature only. Used for required methods in traits (ie,
/// non-default-methods).
Expand Down Expand Up @@ -554,6 +555,7 @@ impl ItemEnum {
ItemEnum::TyMethodItem(ref i) => &i.generics,
ItemEnum::MethodItem(ref i) => &i.generics,
ItemEnum::ForeignFunctionItem(ref f) => &f.generics,
ItemEnum::TraitAliasItem(ref ta) => &ta.generics,
_ => return None,
})
}
Expand Down Expand Up @@ -603,6 +605,7 @@ impl Clean<Item> for doctree::Module {
items.extend(self.impls.iter().flat_map(|x| x.clean(cx)));
items.extend(self.macros.iter().map(|x| x.clean(cx)));
items.extend(self.proc_macros.iter().map(|x| x.clean(cx)));
items.extend(self.trait_aliases.iter().map(|x| x.clean(cx)));

// determine if we should display the inner contents or
// the outer `mod` item for the source code.
Expand Down Expand Up @@ -1885,13 +1888,38 @@ impl Clean<Item> for doctree::Trait {
items: self.items.clean(cx),
generics: self.generics.clean(cx),
bounds: self.bounds.clean(cx),
is_spotlight: is_spotlight,
is_spotlight,
is_auto: self.is_auto.clean(cx),
}),
}
}
}

#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct TraitAlias {
pub generics: Generics,
pub bounds: Vec<GenericBound>,
}

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.whence.clean(cx),
def_id: cx.tcx.hir().local_def_id(self.id),
visibility: self.vis.clean(cx),
stability: self.stab.clean(cx),
deprecation: self.depr.clean(cx),
inner: TraitAliasItem(TraitAlias {
generics: self.generics.clean(cx),
bounds: self.bounds.clean(cx),
}),
}
}
}

impl Clean<bool> for hir::IsAuto {
fn clean(&self, _: &DocContext) -> bool {
match *self {
Expand Down Expand Up @@ -2223,6 +2251,7 @@ pub enum TypeKind {
Macro,
Attr,
Derive,
TraitAlias,
}

pub trait GetDefId {
Expand Down Expand Up @@ -3819,10 +3848,9 @@ pub fn register_def(cx: &DocContext, def: Def) -> DefId {
MacroKind::Derive => (i, TypeKind::Derive),
MacroKind::ProcMacroStub => unreachable!(),
},
Def::TraitAlias(i) => (i, TypeKind::TraitAlias),
Def::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait),
Def::SelfTy(_, Some(impl_def_id)) => {
return impl_def_id
}
Def::SelfTy(_, Some(impl_def_id)) => return impl_def_id,
_ => return def.def_id()
};
if did.is_local() { return did }
Expand Down
44 changes: 29 additions & 15 deletions src/librustdoc/doctree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub struct Module {
pub foreigns: Vec<hir::ForeignMod>,
pub macros: Vec<Macro>,
pub proc_macros: Vec<ProcMacro>,
pub trait_aliases: Vec<TraitAlias>,
pub is_crate: bool,
}

Expand All @@ -53,21 +54,22 @@ impl Module {
where_inner: syntax_pos::DUMMY_SP,
attrs : hir::HirVec::new(),
extern_crates: Vec::new(),
imports : Vec::new(),
structs : Vec::new(),
unions : Vec::new(),
enums : Vec::new(),
fns : Vec::new(),
mods : Vec::new(),
typedefs : Vec::new(),
existentials: Vec::new(),
statics : Vec::new(),
constants : Vec::new(),
traits : Vec::new(),
impls : Vec::new(),
foreigns : Vec::new(),
macros : Vec::new(),
proc_macros: Vec::new(),
imports : Vec::new(),
structs : Vec::new(),
unions : Vec::new(),
enums : Vec::new(),
fns : Vec::new(),
mods : Vec::new(),
typedefs : Vec::new(),
existentials: Vec::new(),
statics : Vec::new(),
constants : Vec::new(),
traits : Vec::new(),
impls : Vec::new(),
foreigns : Vec::new(),
macros : Vec::new(),
proc_macros: Vec::new(),
trait_aliases: Vec::new(),
is_crate : false,
}
}
Expand Down Expand Up @@ -208,6 +210,18 @@ pub struct Trait {
pub depr: Option<attr::Deprecation>,
}

pub struct TraitAlias {
pub name: Name,
pub generics: hir::Generics,
pub bounds: hir::HirVec<hir::GenericBound>,
pub attrs: hir::HirVec<ast::Attribute>,
pub id: ast::NodeId,
pub whence: Span,
pub vis: hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
}

#[derive(Debug)]
pub struct Impl {
pub unsafety: hir::Unsafety,
Expand Down
33 changes: 19 additions & 14 deletions src/librustdoc/html/item_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub enum ItemType {
Existential = 22,
ProcAttribute = 23,
ProcDerive = 24,
TraitAlias = 25,
}


Expand Down Expand Up @@ -86,6 +87,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
clean::AssociatedTypeItem(..) => ItemType::AssociatedType,
clean::ForeignTypeItem => ItemType::ForeignType,
clean::KeywordItem(..) => ItemType::Keyword,
clean::TraitAliasItem(..) => ItemType::TraitAlias,
clean::ProcMacroItem(ref mac) => match mac.kind {
MacroKind::Bang => ItemType::Macro,
MacroKind::Attr => ItemType::ProcAttribute,
Expand All @@ -100,20 +102,21 @@ impl<'a> From<&'a clean::Item> for ItemType {
impl From<clean::TypeKind> for ItemType {
fn from(kind: clean::TypeKind) -> ItemType {
match kind {
clean::TypeKind::Struct => ItemType::Struct,
clean::TypeKind::Union => ItemType::Union,
clean::TypeKind::Enum => ItemType::Enum,
clean::TypeKind::Function => ItemType::Function,
clean::TypeKind::Trait => ItemType::Trait,
clean::TypeKind::Module => ItemType::Module,
clean::TypeKind::Static => ItemType::Static,
clean::TypeKind::Const => ItemType::Constant,
clean::TypeKind::Variant => ItemType::Variant,
clean::TypeKind::Typedef => ItemType::Typedef,
clean::TypeKind::Foreign => ItemType::ForeignType,
clean::TypeKind::Macro => ItemType::Macro,
clean::TypeKind::Attr => ItemType::ProcAttribute,
clean::TypeKind::Derive => ItemType::ProcDerive,
clean::TypeKind::Struct => ItemType::Struct,
clean::TypeKind::Union => ItemType::Union,
clean::TypeKind::Enum => ItemType::Enum,
clean::TypeKind::Function => ItemType::Function,
clean::TypeKind::Trait => ItemType::Trait,
clean::TypeKind::Module => ItemType::Module,
clean::TypeKind::Static => ItemType::Static,
clean::TypeKind::Const => ItemType::Constant,
clean::TypeKind::Variant => ItemType::Variant,
clean::TypeKind::Typedef => ItemType::Typedef,
clean::TypeKind::Foreign => ItemType::ForeignType,
clean::TypeKind::Macro => ItemType::Macro,
clean::TypeKind::Attr => ItemType::ProcAttribute,
clean::TypeKind::Derive => ItemType::ProcDerive,
clean::TypeKind::TraitAlias => ItemType::TraitAlias,
}
}
}
Expand Down Expand Up @@ -146,6 +149,7 @@ impl ItemType {
ItemType::Existential => "existential",
ItemType::ProcAttribute => "attr",
ItemType::ProcDerive => "derive",
ItemType::TraitAlias => "traitalias",
}
}

Expand All @@ -160,6 +164,7 @@ impl ItemType {
ItemType::Primitive |
ItemType::AssociatedType |
ItemType::Existential |
ItemType::TraitAlias |
ItemType::ForeignType => NameSpace::Type,

ItemType::ExternCrate |
Expand Down
42 changes: 31 additions & 11 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1836,6 +1836,7 @@ struct AllTypes {
keywords: FxHashSet<ItemEntry>,
attributes: FxHashSet<ItemEntry>,
derives: FxHashSet<ItemEntry>,
trait_aliases: FxHashSet<ItemEntry>,
}

impl AllTypes {
Expand All @@ -1856,6 +1857,7 @@ impl AllTypes {
keywords: new_set(100),
attributes: new_set(100),
derives: new_set(100),
trait_aliases: new_set(100),
}
}

Expand All @@ -1879,6 +1881,7 @@ impl AllTypes {
ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)),
ItemType::ProcAttribute => self.attributes.insert(ItemEntry::new(new_url, name)),
ItemType::ProcDerive => self.derives.insert(ItemEntry::new(new_url, name)),
ItemType::TraitAlias => self.trait_aliases.insert(ItemEntry::new(new_url, name)),
_ => true,
};
}
Expand Down Expand Up @@ -1922,6 +1925,7 @@ impl fmt::Display for AllTypes {
print_entries(f, &self.derives, "Derive Macros", "derives")?;
print_entries(f, &self.functions, "Functions", "functions")?;
print_entries(f, &self.typedefs, "Typedefs", "typedefs")?;
print_entries(f, &self.trait_aliases, "Trait Aliases", "trait-aliases")?;
print_entries(f, &self.existentials, "Existentials", "existentials")?;
print_entries(f, &self.statics, "Statics", "statics")?;
print_entries(f, &self.constants, "Constants", "constants")
Expand Down Expand Up @@ -2419,6 +2423,7 @@ impl<'a> fmt::Display for Item<'a> {
clean::ForeignTypeItem => write!(fmt, "Foreign Type ")?,
clean::KeywordItem(..) => write!(fmt, "Keyword ")?,
clean::ExistentialItem(..) => write!(fmt, "Existential Type ")?,
clean::TraitAliasItem(..) => write!(fmt, "Trait Alias ")?,
_ => {
// We don't generate pages for any other type.
unreachable!();
Expand Down Expand Up @@ -2457,6 +2462,7 @@ impl<'a> fmt::Display for Item<'a> {
clean::ForeignTypeItem => item_foreign_type(fmt, self.cx, self.item),
clean::KeywordItem(ref k) => item_keyword(fmt, self.cx, self.item, k),
clean::ExistentialItem(ref e, _) => item_existential(fmt, self.cx, self.item, e),
clean::TraitAliasItem(ref ta) => item_trait_alias(fmt, self.cx, self.item, ta),
_ => {
// We don't generate pages for any other type.
unreachable!();
Expand Down Expand Up @@ -3014,23 +3020,17 @@ fn render_impls(cx: &Context, w: &mut fmt::Formatter,
Ok(())
}

fn bounds(t_bounds: &[clean::GenericBound]) -> String {
fn bounds(t_bounds: &[clean::GenericBound], trait_alias: bool) -> String {
let mut bounds = String::new();
let mut bounds_plain = String::new();
if !t_bounds.is_empty() {
if !bounds.is_empty() {
bounds.push(' ');
bounds_plain.push(' ');
if !trait_alias {
bounds.push_str(": ");
}
bounds.push_str(": ");
bounds_plain.push_str(": ");
for (i, p) in t_bounds.iter().enumerate() {
if i > 0 {
bounds.push_str(" + ");
bounds_plain.push_str(" + ");
}
bounds.push_str(&(*p).to_string());
bounds_plain.push_str(&format!("{:#}", *p));
}
}
bounds
Expand All @@ -3050,7 +3050,7 @@ fn item_trait(
it: &clean::Item,
t: &clean::Trait,
) -> fmt::Result {
let bounds = bounds(&t.bounds);
let bounds = bounds(&t.bounds, false);
let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>();
let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>();
let required = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>();
Expand Down Expand Up @@ -4280,7 +4280,26 @@ fn item_existential(
it.name.as_ref().unwrap(),
t.generics,
where_clause = WhereClause { gens: &t.generics, indent: 0, end_newline: true },
bounds = bounds(&t.bounds))?;
bounds = bounds(&t.bounds, false))?;

document(w, cx, it)?;

// Render any items associated directly to this alias, as otherwise they
// won't be visible anywhere in the docs. It would be nice to also show
// associated items from the aliased type (see discussion in #32077), but
// we need #14072 to make sense of the generics.
render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)
}

fn item_trait_alias(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
t: &clean::TraitAlias) -> fmt::Result {
write!(w, "<pre class='rust trait-alias'>")?;
render_attributes(w, it)?;
write!(w, "trait {}{}{} = {};</pre>",
it.name.as_ref().unwrap(),
t.generics,
WhereClause { gens: &t.generics, indent: 0, end_newline: true },
bounds(&t.bounds, true))?;

document(w, cx, it)?;

Expand Down Expand Up @@ -4844,6 +4863,7 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
ItemType::Existential => ("existentials", "Existentials"),
ItemType::ProcAttribute => ("attributes", "Attribute Macros"),
ItemType::ProcDerive => ("derives", "Derive Macros"),
ItemType::TraitAlias => ("trait-aliases", "Trait aliases"),
}
}

Expand Down
4 changes: 3 additions & 1 deletion src/librustdoc/html/static/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ if (!DOMTokenList.prototype.remove) {
"keyword",
"existential",
"attr",
"derive"];
"derive",
"traitalias"];

var search_input = document.getElementsByClassName("search-input")[0];

Expand Down Expand Up @@ -1786,6 +1787,7 @@ if (!DOMTokenList.prototype.remove) {
block("type", "Type Definitions");
block("foreigntype", "Foreign Types");
block("keyword", "Keywords");
block("traitalias", "Trait Aliases");
}

window.initSidebarItems = initSidebarItems;
Expand Down
2 changes: 2 additions & 0 deletions src/librustdoc/html/static/themes/dark.css
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ pre {
}
.content .highlighted a, .content .highlighted span { color: #eee !important; }
.content .highlighted.trait { background-color: #013191; }
.content .highlighted.traitalias { background-color: #013191; }
.content .highlighted.mod,
.content .highlighted.externcrate { background-color: #afc6e4; }
.content .highlighted.mod { background-color: #803a1b; }
Expand Down Expand Up @@ -128,6 +129,7 @@ pre {
.content span.externcrate,
.content span.mod, .content a.mod, .block a.current.mod { color: #bda000; }
.content span.trait, .content a.trait, .block a.current.trait { color: #b78cf2; }
.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #b397da; }
.content span.fn, .content a.fn, .block a.current.fn,
.content span.method, .content a.method, .block a.current.method,
.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
Expand Down
2 changes: 2 additions & 0 deletions src/librustdoc/html/static/themes/light.css
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pre {
}
.content .highlighted a, .content .highlighted span { color: #000 !important; }
.content .highlighted.trait { background-color: #c7b6ff; }
.content .highlighted.traitalias { background-color: #c7b6ff; }
.content .highlighted.mod,
.content .highlighted.externcrate { background-color: #afc6e4; }
.content .highlighted.enum { background-color: #b4d1b9; }
Expand Down Expand Up @@ -128,6 +129,7 @@ pre {
.content span.externcrate,
.content span.mod, .content a.mod, .block a.current.mod { color: #4d76ae; }
.content span.trait, .content a.trait, .block a.current.trait { color: #7c5af3; }
.content span.traitalias, .content a.traitalias, .block a.current.traitalias { color: #6841f1; }
.content span.fn, .content a.fn, .block a.current.fn,
.content span.method, .content a.method, .block a.current.method,
.content span.tymethod, .content a.tymethod, .block a.current.tymethod,
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/passes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
| clean::ConstantItem(..)
| clean::UnionItem(..)
| clean::AssociatedConstItem(..)
| clean::TraitAliasItem(..)
| clean::ForeignTypeItem => {
if i.def_id.is_local() {
if !self.access_levels.is_exported(i.def_id) {
Expand Down
Loading