Implement generalized object and type parameter bounds (Fixes #16462)

This commit is contained in:
Niko Matsakis 2014-08-27 21:46:52 -04:00
parent 3ee047ae1f
commit 1b487a8906
272 changed files with 6783 additions and 3154 deletions

View file

@ -159,18 +159,12 @@ pub fn build_external_trait(tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait {
clean::RequiredMethod(trait_item)
}
});
let supertraits = ty::trait_supertraits(tcx, did);
let mut parents = supertraits.iter().map(|i| {
match i.clean() {
clean::TraitBound(ty) => ty,
clean::RegionBound => unreachable!()
}
});
let trait_def = ty::lookup_trait_def(tcx, did);
let bounds = trait_def.bounds.clean();
clean::Trait {
generics: (&def.generics, subst::TypeSpace).clean(),
items: items.collect(),
parents: parents.collect()
bounds: bounds,
}
}

View file

@ -481,15 +481,14 @@ impl Clean<TyParam> for ty::TypeParameterDef {
#[deriving(Clone, Encodable, Decodable, PartialEq)]
pub enum TyParamBound {
RegionBound,
RegionBound, // FIXME(#16518) -- need to include name of actual region
TraitBound(Type)
}
impl Clean<TyParamBound> for ast::TyParamBound {
fn clean(&self) -> TyParamBound {
match *self {
ast::StaticRegionTyParamBound => RegionBound,
ast::OtherRegionTyParamBound(_) => RegionBound,
ast::RegionTyParamBound(_) => RegionBound,
ast::UnboxedFnTyParamBound(_) => {
// FIXME(pcwalton): Wrong.
RegionBound
@ -499,6 +498,16 @@ impl Clean<TyParamBound> for ast::TyParamBound {
}
}
impl Clean<Vec<TyParamBound>> for ty::ExistentialBounds {
fn clean(&self) -> Vec<TyParamBound> {
let mut vec = vec!(RegionBound);
for bb in self.builtin_bounds.iter() {
vec.push(bb.clean());
}
vec
}
}
fn external_path(name: &str, substs: &subst::Substs) -> Path {
let lifetimes = substs.regions().get_slice(subst::TypeSpace)
.iter()
@ -525,7 +534,6 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
};
let empty = subst::Substs::empty();
let (did, path) = match *self {
ty::BoundStatic => return RegionBound,
ty::BoundSend =>
(tcx.lang_items.send_trait().unwrap(),
external_path("Send", &empty)),
@ -810,10 +818,7 @@ impl Clean<ClosureDecl> for ast::ClosureTy {
decl: self.decl.clean(),
onceness: self.onceness,
fn_style: self.fn_style,
bounds: match self.bounds {
Some(ref x) => x.clean(),
None => Vec::new()
},
bounds: self.bounds.clean()
}
}
}
@ -909,7 +914,7 @@ impl Clean<RetStyle> for ast::RetStyle {
pub struct Trait {
pub items: Vec<TraitItem>,
pub generics: Generics,
pub parents: Vec<Type>,
pub bounds: Vec<TyParamBound>,
}
impl Clean<Item> for doctree::Trait {
@ -924,7 +929,7 @@ impl Clean<Item> for doctree::Trait {
inner: TraitItem(Trait {
items: self.items.clean(),
generics: self.generics.clean(),
parents: self.parents.clean(),
bounds: self.bounds.clean(),
}),
}
}
@ -1060,7 +1065,7 @@ pub enum Type {
Self(ast::DefId),
/// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
Primitive(Primitive),
Closure(Box<ClosureDecl>, Option<Lifetime>),
Closure(Box<ClosureDecl>),
Proc(Box<ClosureDecl>),
/// extern "ABI" fn
BareFunction(Box<BareFunctionDecl>),
@ -1208,7 +1213,7 @@ impl Clean<Type> for ast::Ty {
tpbs.clean().map(|x| x),
id)
}
TyClosure(ref c, region) => Closure(box c.clean(), region.clean()),
TyClosure(ref c) => Closure(box c.clean()),
TyProc(ref c) => Proc(box c.clean()),
TyBareFn(ref barefn) => BareFunction(box barefn.clean()),
TyParen(ref ty) => ty.clean(),
@ -1273,11 +1278,11 @@ impl Clean<Type> for ty::t {
decl: (ast_util::local_def(0), &fty.sig).clean(),
onceness: fty.onceness,
fn_style: fty.fn_style,
bounds: fty.bounds.iter().map(|i| i.clean()).collect(),
bounds: fty.bounds.clean(),
};
match fty.store {
ty::UniqTraitStore => Proc(decl),
ty::RegionTraitStore(ref r, _) => Closure(decl, r.clean()),
ty::RegionTraitStore(..) => Closure(decl),
}
}
ty::ty_struct(did, ref substs) |

View file

@ -156,7 +156,7 @@ pub struct Trait {
pub name: Ident,
pub items: Vec<ast::TraitItem>, //should be TraitItem
pub generics: ast::Generics,
pub parents: Vec<ast::TraitRef>,
pub bounds: Vec<ast::TyParamBound>,
pub attrs: Vec<ast::Attribute>,
pub id: ast::NodeId,
pub whence: Span,

View file

@ -355,7 +355,7 @@ impl fmt::Show for clean::Type {
}
clean::Self(..) => f.write("Self".as_bytes()),
clean::Primitive(prim) => primitive_link(f, prim, prim.to_string()),
clean::Closure(ref decl, ref region) => {
clean::Closure(ref decl) => {
write!(f, "{style}{lifetimes}|{args}|{bounds}{arrow}",
style = FnStyleSpace(decl.fn_style),
lifetimes = if decl.lifetimes.len() == 0 {
@ -370,13 +370,6 @@ impl fmt::Show for clean::Type {
},
bounds = {
let mut ret = String::new();
match *region {
Some(ref lt) => {
ret.push_str(format!(": {}",
*lt).as_slice());
}
None => {}
}
for bound in decl.bounds.iter() {
match *bound {
clean::RegionBound => {}

View file

@ -1610,12 +1610,12 @@ fn item_function(w: &mut fmt::Formatter, it: &clean::Item,
fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
t: &clean::Trait) -> fmt::Result {
let mut parents = String::new();
if t.parents.len() > 0 {
parents.push_str(": ");
for (i, p) in t.parents.iter().enumerate() {
if i > 0 { parents.push_str(" + "); }
parents.push_str(format!("{}", *p).as_slice());
let mut bounds = String::new();
if t.bounds.len() > 0 {
bounds.push_str(": ");
for (i, p) in t.bounds.iter().enumerate() {
if i > 0 { bounds.push_str(" + "); }
bounds.push_str(format!("{}", *p).as_slice());
}
}
@ -1624,7 +1624,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item,
VisSpace(it.visibility),
it.name.get_ref().as_slice(),
t.generics,
parents));
bounds));
let required = t.items.iter()
.filter(|m| {
match **m {

View file

@ -317,12 +317,12 @@ impl<'a> RustdocVisitor<'a> {
};
om.statics.push(s);
},
ast::ItemTrait(ref gen, _, ref tr, ref items) => {
ast::ItemTrait(ref gen, _, ref b, ref items) => {
let t = Trait {
name: item.ident,
items: items.iter().map(|x| (*x).clone()).collect(),
generics: gen.clone(),
parents: tr.iter().map(|x| (*x).clone()).collect(),
bounds: b.iter().map(|x| (*x).clone()).collect(),
id: item.id,
attrs: item.attrs.iter().map(|x| *x).collect(),
whence: item.span,