Implement existential types

This commit is contained in:
Oliver Schneider 2018-07-03 19:38:14 +02:00
parent 1c84d81873
commit 53d2ebb0ad
182 changed files with 1389 additions and 121 deletions

View file

@ -512,6 +512,7 @@ pub enum ItemEnum {
FunctionItem(Function),
ModuleItem(Module),
TypedefItem(Typedef, bool /* is associated type */),
ExistentialItem(Existential, bool /* is associated type */),
StaticItem(Static),
ConstantItem(Constant),
TraitItem(Trait),
@ -545,6 +546,7 @@ impl ItemEnum {
ItemEnum::EnumItem(ref e) => &e.generics,
ItemEnum::FunctionItem(ref f) => &f.generics,
ItemEnum::TypedefItem(ref t, _) => &t.generics,
ItemEnum::ExistentialItem(ref t, _) => &t.generics,
ItemEnum::TraitItem(ref t) => &t.generics,
ItemEnum::ImplItem(ref i) => &i.generics,
ItemEnum::TyMethodItem(ref i) => &i.generics,
@ -596,6 +598,7 @@ impl Clean<Item> for doctree::Module {
items.extend(self.foreigns.iter().flat_map(|x| x.clean(cx)));
items.extend(self.mods.iter().map(|x| x.clean(cx)));
items.extend(self.typedefs.iter().map(|x| x.clean(cx)));
items.extend(self.existentials.iter().map(|x| x.clean(cx)));
items.extend(self.statics.iter().map(|x| x.clean(cx)));
items.extend(self.constants.iter().map(|x| x.clean(cx)));
items.extend(self.traits.iter().map(|x| x.clean(cx)));
@ -2411,6 +2414,10 @@ impl Clean<Item> for hir::ImplItem {
type_: ty.clean(cx),
generics: Generics::default(),
}, true),
hir::ImplItemKind::Existential(ref bounds) => ExistentialItem(Existential {
bounds: bounds.clean(cx),
generics: Generics::default(),
}, true),
};
Item {
name: Some(self.ident.name.clean(cx)),
@ -2554,6 +2561,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
}, true)
}
}
ty::AssociatedKind::Existential => unimplemented!(),
};
let visibility = match self.container {
@ -3696,6 +3704,30 @@ impl Clean<Item> for doctree::Typedef {
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct Existential {
pub bounds: Vec<GenericBound>,
pub generics: Generics,
}
impl Clean<Item> for doctree::Existential {
fn clean(&self, cx: &DocContext) -> Item {
Item {
name: Some(self.name.clean(cx)),
attrs: self.attrs.clean(cx),
source: self.whence.clean(cx),
def_id: cx.tcx.hir.local_def_id(self.id.clone()),
visibility: self.vis.clean(cx),
stability: self.stab.clean(cx),
deprecation: self.depr.clean(cx),
inner: ExistentialItem(Existential {
bounds: self.exist_ty.bounds.clean(cx),
generics: self.exist_ty.generics.clean(cx),
}, false),
}
}
}
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
pub struct BareFunctionDecl {
pub unsafety: hir::Unsafety,

View file

@ -37,6 +37,7 @@ pub struct Module {
pub mods: Vec<Module>,
pub id: NodeId,
pub typedefs: Vec<Typedef>,
pub existentials: Vec<Existential>,
pub statics: Vec<Static>,
pub constants: Vec<Constant>,
pub traits: Vec<Trait>,
@ -68,6 +69,7 @@ impl Module {
fns : Vec::new(),
mods : Vec::new(),
typedefs : Vec::new(),
existentials: Vec::new(),
statics : Vec::new(),
constants : Vec::new(),
traits : Vec::new(),
@ -167,6 +169,17 @@ pub struct Typedef {
pub depr: Option<attr::Deprecation>,
}
pub struct Existential {
pub exist_ty: hir::ExistTy,
pub name: Name,
pub id: ast::NodeId,
pub attrs: hir::HirVec<ast::Attribute>,
pub whence: Span,
pub vis: hir::Visibility,
pub stab: Option<attr::Stability>,
pub depr: Option<attr::Deprecation>,
}
#[derive(Debug)]
pub struct Static {
pub type_: P<hir::Ty>,

View file

@ -43,6 +43,7 @@ pub enum ItemType {
Union = 19,
ForeignType = 20,
Keyword = 21,
Existential = 22,
}
@ -70,6 +71,7 @@ impl<'a> From<&'a clean::Item> for ItemType {
clean::EnumItem(..) => ItemType::Enum,
clean::FunctionItem(..) => ItemType::Function,
clean::TypedefItem(..) => ItemType::Typedef,
clean::ExistentialItem(..) => ItemType::Existential,
clean::StaticItem(..) => ItemType::Static,
clean::ConstantItem(..) => ItemType::Constant,
clean::TraitItem(..) => ItemType::Trait,
@ -135,6 +137,7 @@ impl ItemType {
ItemType::AssociatedConst => "associatedconstant",
ItemType::ForeignType => "foreigntype",
ItemType::Keyword => "keyword",
ItemType::Existential => "existential",
}
}
@ -148,6 +151,7 @@ impl ItemType {
ItemType::Trait |
ItemType::Primitive |
ItemType::AssociatedType |
ItemType::Existential |
ItemType::ForeignType => NameSpace::Type,
ItemType::ExternCrate |

View file

@ -1570,6 +1570,7 @@ struct AllTypes {
macros: HashSet<ItemEntry>,
functions: HashSet<ItemEntry>,
typedefs: HashSet<ItemEntry>,
existentials: HashSet<ItemEntry>,
statics: HashSet<ItemEntry>,
constants: HashSet<ItemEntry>,
keywords: HashSet<ItemEntry>,
@ -1586,6 +1587,7 @@ impl AllTypes {
macros: HashSet::with_capacity(100),
functions: HashSet::with_capacity(100),
typedefs: HashSet::with_capacity(100),
existentials: HashSet::with_capacity(100),
statics: HashSet::with_capacity(100),
constants: HashSet::with_capacity(100),
keywords: HashSet::with_capacity(100),
@ -1607,6 +1609,7 @@ impl AllTypes {
ItemType::Macro => self.macros.insert(ItemEntry::new(new_url, name)),
ItemType::Function => self.functions.insert(ItemEntry::new(new_url, name)),
ItemType::Typedef => self.typedefs.insert(ItemEntry::new(new_url, name)),
ItemType::Existential => self.existentials.insert(ItemEntry::new(new_url, name)),
ItemType::Static => self.statics.insert(ItemEntry::new(new_url, name)),
ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)),
_ => true,
@ -1650,6 +1653,7 @@ impl fmt::Display for AllTypes {
print_entries(f, &self.macros, "Macros", "macros")?;
print_entries(f, &self.functions, "Functions", "functions")?;
print_entries(f, &self.typedefs, "Typedefs", "typedefs")?;
print_entries(f, &self.existentials, "Existentials", "existentials")?;
print_entries(f, &self.statics, "Statics", "statics")?;
print_entries(f, &self.constants, "Constants", "constants")
}
@ -4400,6 +4404,7 @@ fn item_ty_to_strs(ty: &ItemType) -> (&'static str, &'static str) {
ItemType::AssociatedConst => ("associated-consts", "Associated Constants"),
ItemType::ForeignType => ("foreign-types", "Foreign Types"),
ItemType::Keyword => ("keywords", "Keywords"),
ItemType::Existential => ("existentials", "Existentials"),
}
}

View file

@ -84,6 +84,7 @@ impl<'a> fold::DocFolder for Stripper<'a> {
return ret;
}
// These items can all get re-exported
clean::ExistentialItem(..) |
clean::TypedefItem(..) | clean::StaticItem(..) |
clean::StructItem(..) | clean::EnumItem(..) |
clean::TraitItem(..) | clean::FunctionItem(..) |

View file

@ -439,6 +439,19 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
};
om.typedefs.push(t);
},
hir::ItemKind::Existential(ref exist_ty) => {
let t = Existential {
exist_ty: exist_ty.clone(),
name,
id: item.id,
attrs: item.attrs.clone(),
whence: item.span,
vis: item.vis.clone(),
stab: self.stability(item.id),
depr: self.deprecation(item.id),
};
om.existentials.push(t);
},
hir::ItemKind::Static(ref ty, ref mut_, ref exp) => {
let s = Static {
type_: ty.clone(),
@ -523,9 +536,6 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> {
om.impls.push(i);
}
},
hir::ItemKind::Existential(_) => {
// FIXME(oli-obk): actually generate docs for real existential items
}
}
}