X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustdoc%2Fhtml%2Frender.rs;h=692d230446cda7b356b028021237f610c28bb141;hb=37c6f2881c634fe72dc98b846037dc1237270659;hp=dfbe08a0e423d2d204914dbb69cc5185d4a2224b;hpb=cd418ba09b22e337e48f7e56249b43146e2df539;p=rust.git diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index dfbe08a0e42..692d230446c 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -52,7 +52,7 @@ use externalfiles::ExternalHtml; -use serialize::json::{self, ToJson}; +use serialize::json::{ToJson, Json, as_json}; use syntax::{abi, ast}; use syntax::feature_gate::UnstableFeatures; use rustc::middle::cstore::LOCAL_CRATE; @@ -290,22 +290,40 @@ struct IndexItem { path: String, desc: String, parent: Option, + parent_idx: Option, search_type: Option, } +impl ToJson for IndexItem { + fn to_json(&self) -> Json { + assert_eq!(self.parent.is_some(), self.parent_idx.is_some()); + + let mut data = Vec::with_capacity(6); + data.push((self.ty as usize).to_json()); + data.push(self.name.to_json()); + data.push(self.path.to_json()); + data.push(self.desc.to_json()); + data.push(self.parent_idx.to_json()); + data.push(self.search_type.to_json()); + + Json::Array(data) + } +} + /// A type used for the search index. struct Type { name: Option, } -impl fmt::Display for Type { - /// Formats type as {name: $name}. - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // Wrapping struct fmt should never call us when self.name is None, - // but just to be safe we write `null` in that case. +impl ToJson for Type { + fn to_json(&self) -> Json { match self.name { - Some(ref n) => write!(f, "{{\"name\":\"{}\"}}", n), - None => write!(f, "null") + Some(ref name) => { + let mut data = BTreeMap::new(); + data.insert("name".to_owned(), name.to_json()); + Json::Object(data) + }, + None => Json::Null } } } @@ -316,26 +334,17 @@ struct IndexItemFunctionType { output: Option } -impl fmt::Display for IndexItemFunctionType { - /// Formats a full fn type as a JSON {inputs: [Type], outputs: Type/null}. - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { +impl ToJson for IndexItemFunctionType { + fn to_json(&self) -> Json { // If we couldn't figure out a type, just write `null`. - if self.inputs.iter().any(|ref i| i.name.is_none()) || - (self.output.is_some() && self.output.as_ref().unwrap().name.is_none()) { - return write!(f, "null") + if self.inputs.iter().chain(self.output.iter()).any(|ref i| i.name.is_none()) { + Json::Null + } else { + let mut data = BTreeMap::new(); + data.insert("inputs".to_owned(), self.inputs.to_json()); + data.insert("output".to_owned(), self.output.to_json()); + Json::Object(data) } - - let inputs: Vec = self.inputs.iter().map(|ref t| { - format!("{}", t) - }).collect(); - try!(write!(f, "{{\"inputs\":[{}],\"output\":", inputs.join(","))); - - match self.output { - Some(ref t) => try!(write!(f, "{}", t)), - None => try!(write!(f, "null")) - }; - - Ok(try!(write!(f, "}}"))) } } @@ -534,101 +543,79 @@ pub fn run(mut krate: clean::Crate, cx.krate(krate) } +/// Build the search index from the collected metadata fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { - // Build the search index from the collected metadata let mut nodeid_to_pathid = HashMap::new(); - let mut pathid_to_nodeid = Vec::new(); - { - let Cache { ref mut search_index, - ref orphan_methods, - ref mut paths, .. } = *cache; - - // Attach all orphan methods to the type's definition if the type - // has since been learned. - for &(did, ref item) in orphan_methods { - match paths.get(&did) { - Some(&(ref fqp, _)) => { - // Needed to determine `self` type. - let parent_basename = Some(fqp[fqp.len() - 1].clone()); - search_index.push(IndexItem { - ty: shortty(item), - name: item.name.clone().unwrap(), - path: fqp[..fqp.len() - 1].join("::"), - desc: shorter(item.doc_value()), - parent: Some(did), - search_type: get_index_search_type(&item, parent_basename), - }); - }, - None => {} - } - } + let mut crate_items = Vec::with_capacity(cache.search_index.len()); + let mut crate_paths = Vec::::new(); + + let Cache { ref mut search_index, + ref orphan_methods, + ref mut paths, .. } = *cache; + + // Attach all orphan methods to the type's definition if the type + // has since been learned. + for &(did, ref item) in orphan_methods { + match paths.get(&did) { + Some(&(ref fqp, _)) => { + // Needed to determine `self` type. + let parent_basename = Some(fqp[fqp.len() - 1].clone()); + search_index.push(IndexItem { + ty: shortty(item), + name: item.name.clone().unwrap(), + path: fqp[..fqp.len() - 1].join("::"), + desc: Escape(&shorter(item.doc_value())).to_string(), + parent: Some(did), + parent_idx: None, + search_type: get_index_search_type(&item, parent_basename), + }); + }, + None => {} + } + } + + // Reduce `NodeId` in paths into smaller sequential numbers, + // and prune the paths that do not appear in the index. + let mut lastpath = String::new(); + let mut lastpathid = 0usize; + + for item in search_index { + item.parent_idx = item.parent.map(|nodeid| { + if nodeid_to_pathid.contains_key(&nodeid) { + *nodeid_to_pathid.get(&nodeid).unwrap() + } else { + let pathid = lastpathid; + nodeid_to_pathid.insert(nodeid, pathid); + lastpathid += 1; - // Reduce `NodeId` in paths into smaller sequential numbers, - // and prune the paths that do not appear in the index. - for item in search_index.iter() { - match item.parent { - Some(nodeid) => { - if !nodeid_to_pathid.contains_key(&nodeid) { - let pathid = pathid_to_nodeid.len(); - nodeid_to_pathid.insert(nodeid, pathid); - pathid_to_nodeid.push(nodeid); - } - } - None => {} + let &(ref fqp, short) = paths.get(&nodeid).unwrap(); + crate_paths.push(((short as usize), fqp.last().unwrap().clone()).to_json()); + pathid } - } - assert_eq!(nodeid_to_pathid.len(), pathid_to_nodeid.len()); - } - - // Collect the index into a string - let mut w = io::Cursor::new(Vec::new()); - write!(&mut w, r#"searchIndex['{}'] = {{"items":["#, krate.name).unwrap(); + }); - let mut lastpath = "".to_string(); - for (i, item) in cache.search_index.iter().enumerate() { - // Omit the path if it is same to that of the prior item. - let path; + // Omit the parent path if it is same to that of the prior item. if lastpath == item.path { - path = ""; + item.path.clear(); } else { - lastpath = item.path.to_string(); - path = &item.path; - }; - - if i > 0 { - write!(&mut w, ",").unwrap(); + lastpath = item.path.clone(); } - write!(&mut w, r#"[{},"{}","{}",{}"#, - item.ty as usize, item.name, path, - item.desc.to_json().to_string()).unwrap(); - match item.parent { - Some(nodeid) => { - let pathid = *nodeid_to_pathid.get(&nodeid).unwrap(); - write!(&mut w, ",{}", pathid).unwrap(); - } - None => write!(&mut w, ",null").unwrap() - } - match item.search_type { - Some(ref t) => write!(&mut w, ",{}", t).unwrap(), - None => write!(&mut w, ",null").unwrap() - } - write!(&mut w, "]").unwrap(); + crate_items.push(item.to_json()); } - write!(&mut w, r#"],"paths":["#).unwrap(); - - for (i, &did) in pathid_to_nodeid.iter().enumerate() { - let &(ref fqp, short) = cache.paths.get(&did).unwrap(); - if i > 0 { - write!(&mut w, ",").unwrap(); - } - write!(&mut w, r#"[{},"{}"]"#, - short as usize, *fqp.last().unwrap()).unwrap(); - } + let crate_doc = krate.module.as_ref().map(|module| { + Escape(&shorter(module.doc_value())).to_string() + }).unwrap_or(String::new()); - write!(&mut w, "]}};").unwrap(); + let mut crate_data = BTreeMap::new(); + crate_data.insert("doc".to_owned(), Json::String(crate_doc)); + crate_data.insert("items".to_owned(), Json::Array(crate_items)); + crate_data.insert("paths".to_owned(), Json::Array(crate_paths)); - String::from_utf8(w.into_inner()).unwrap() + // Collect the index into a string + format!("searchIndex[{}] = {};", + as_json(&krate.name), + Json::Object(crate_data)) } fn write_shared(cx: &Context, @@ -693,7 +680,7 @@ fn collect(path: &Path, krate: &str, if !line.starts_with(key) { continue } - if line.starts_with(&format!("{}['{}']", key, krate)) { + if line.starts_with(&format!(r#"{}["{}"]"#, key, krate)) { continue } ret.push(line.to_string()); @@ -1065,8 +1052,9 @@ fn fold_item(&mut self, item: clean::Item) -> Option { ty: shortty(&item), name: s.to_string(), path: path.join("::").to_string(), - desc: shorter(item.doc_value()), + desc: Escape(&shorter(item.doc_value())).to_string(), parent: parent, + parent_idx: None, search_type: get_index_search_type(&item, parent_basename), }); } @@ -1387,7 +1375,7 @@ fn render(w: File, cx: &Context, it: &clean::Item, let js_dst = this.dst.join("sidebar-items.js"); let mut js_out = BufWriter::new(try_err!(File::create(&js_dst), &js_dst)); try_err!(write!(&mut js_out, "initSidebarItems({});", - json::as_json(&items)), &js_dst); + as_json(&items)), &js_dst); } for item in m.items { @@ -1501,11 +1489,17 @@ fn href(&self, cx: &Context) -> Option { true, |component| { path.push(component.to_string()); }); - Some(format!("{root}src/{krate}/{path}.html#{href}", - root = self.cx.root_path, - krate = self.cx.layout.krate, - path = path.join("/"), - href = href)) + // If the span points into an external macro the + // source-file will be bogus, i.e `` + if Path::new(&self.item.source.filename).is_file() { + Some(format!("{root}src/{krate}/{path}.html#{href}", + root = self.cx.root_path, + krate = self.cx.layout.krate, + path = path.join("/"), + href = href)) + } else { + None + } // If this item is not part of the local crate, then things get a little // trickier. We don't actually know the span of the external item, but @@ -1653,8 +1647,8 @@ fn shorter<'a>(s: Option<&'a str>) -> String { #[inline] fn plain_summary_line(s: Option<&str>) -> String { - let line = shorter(s).replace("\n", " "); - markdown::plain_summary_line(&line[..]) + let md = markdown::plain_summary_line(s.unwrap_or("")); + shorter(Some(&md)).replace("\n", " ") } fn document(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item) -> fmt::Result { @@ -1781,6 +1775,7 @@ fn cmp(i1: &clean::Item, i2: &clean::Item, idx1: usize, idx2: usize) -> Ordering } else { String::new() }; + let doc_value = myitem.doc_value().unwrap_or(""); try!(write!(w, " Ordering ", name = *myitem.name.as_ref().unwrap(), stab_docs = stab_docs, - docs = Markdown(&shorter(myitem.doc_value())), + docs = shorter(Some(&Markdown(doc_value).to_string())), class = shortty(myitem), stab = myitem.stability_class(), href = item_path(myitem), @@ -1913,6 +1908,7 @@ fn item_function(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, generics = f.generics, where_clause = WhereClause(&f.generics), decl = f.decl)); + try!(render_stability_since_raw(w, it.stable_since(), None)); document(w, cx, it) } @@ -1992,7 +1988,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, // Trait documentation try!(document(w, cx, it)); - fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item) + fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item, t: &clean::Item) -> fmt::Result { let name = m.name.as_ref().unwrap(); let id = derive_id(format!("{}.{}", shortty(m), name)); @@ -2000,7 +1996,9 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item) id = id, stab = m.stability_class())); try!(render_assoc_item(w, m, AssocItemLink::Anchor)); - try!(write!(w, "")); + try!(write!(w, "")); + try!(render_stability_since(w, m, t)); + try!(write!(w, "")); try!(document(w, cx, m)); Ok(()) } @@ -2011,7 +2009,7 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item)
")); for t in &types { - try!(trait_item(w, cx, *t)); + try!(trait_item(w, cx, *t, it)); } try!(write!(w, "
")); } @@ -2022,7 +2020,7 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item)
")); for t in &consts { - try!(trait_item(w, cx, *t)); + try!(trait_item(w, cx, *t, it)); } try!(write!(w, "
")); } @@ -2034,7 +2032,7 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item)
")); for m in &required { - try!(trait_item(w, cx, *m)); + try!(trait_item(w, cx, *m, it)); } try!(write!(w, "
")); } @@ -2044,13 +2042,13 @@ fn trait_item(w: &mut fmt::Formatter, cx: &Context, m: &clean::Item)
")); for m in &provided { - try!(trait_item(w, cx, *m)); + try!(trait_item(w, cx, *m, it)); } try!(write!(w, "
")); } // If there are methods directly on this trait object, render them here. - try!(render_assoc_items(w, cx, it.def_id, AssocItemRender::All)); + try!(render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)); let cache = cache(); try!(write!(w, " @@ -2106,6 +2104,29 @@ fn assoc_type(w: &mut fmt::Formatter, it: &clean::Item, Ok(()) } +fn render_stability_since_raw<'a>(w: &mut fmt::Formatter, + ver: Option<&'a str>, + containing_ver: Option<&'a str>) -> fmt::Result { + if containing_ver != ver { + match ver { + Some(v) => + if v.len() > 0 { + try!(write!(w, "{}", + v)) + }, + None => {} + } + } + + Ok(()) +} + +fn render_stability_since(w: &mut fmt::Formatter, + item: &clean::Item, + containing_item: &clean::Item) -> fmt::Result { + render_stability_since_raw(w, item.stable_since(), containing_item.stable_since()) +} + fn render_assoc_item(w: &mut fmt::Formatter, meth: &clean::Item, link: AssocItemLink) -> fmt::Result { fn method(w: &mut fmt::Formatter, @@ -2178,6 +2199,7 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, "", true)); try!(write!(w, "")); + try!(render_stability_since_raw(w, it.stable_since(), None)); try!(document(w, cx, it)); let mut fields = s.fields.iter().filter(|f| { @@ -2202,7 +2224,7 @@ fn item_struct(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, try!(write!(w, "")); } } - render_assoc_items(w, cx, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, @@ -2257,10 +2279,11 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, try!(write!(w, "}}")); } try!(write!(w, "")); + try!(render_stability_since_raw(w, it.stable_since(), None)); try!(document(w, cx, it)); if !e.variants.is_empty() { - try!(write!(w, "

Variants

\n")); + try!(write!(w, "

Variants

\n
")); for variant in &e.variants { try!(write!(w, "")); } try!(write!(w, "
{name}", name = variant.name.as_ref().unwrap())); @@ -2296,12 +2319,14 @@ fn item_enum(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, } _ => () } + try!(write!(w, "")); + try!(render_stability_since(w, variant, it)); try!(write!(w, "
")); } - try!(render_assoc_items(w, cx, it.def_id, AssocItemRender::All)); + try!(render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)); Ok(()) } @@ -2397,6 +2422,7 @@ enum AssocItemRender<'a> { fn render_assoc_items(w: &mut fmt::Formatter, cx: &Context, + containing_item: &clean::Item, it: DefId, what: AssocItemRender) -> fmt::Result { let c = cache(); @@ -2420,7 +2446,8 @@ fn render_assoc_items(w: &mut fmt::Formatter, } }; for i in &non_trait { - try!(render_impl(w, cx, i, AssocItemLink::Anchor, render_header)); + try!(render_impl(w, cx, i, AssocItemLink::Anchor, render_header, + containing_item.stable_since())); } } if let AssocItemRender::DerefFor { .. } = what { @@ -2436,7 +2463,7 @@ fn render_assoc_items(w: &mut fmt::Formatter, } }); if let Some(impl_) = deref_impl { - try!(render_deref_methods(w, cx, impl_)); + try!(render_deref_methods(w, cx, impl_, containing_item)); } try!(write!(w, "

Trait \ Implementations

")); @@ -2445,7 +2472,8 @@ fn render_assoc_items(w: &mut fmt::Formatter, }); for i in &manual { let did = i.trait_did().unwrap(); - try!(render_impl(w, cx, i, AssocItemLink::GotoSource(did), true)); + try!(render_impl(w, cx, i, AssocItemLink::GotoSource(did), true, + containing_item.stable_since())); } if !derived.is_empty() { try!(write!(w, "

\ @@ -2453,14 +2481,16 @@ fn render_assoc_items(w: &mut fmt::Formatter,

")); for i in &derived { let did = i.trait_did().unwrap(); - try!(render_impl(w, cx, i, AssocItemLink::GotoSource(did), true)); + try!(render_impl(w, cx, i, AssocItemLink::GotoSource(did), true, + containing_item.stable_since())); } } } Ok(()) } -fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl) -> fmt::Result { +fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl, + container_item: &clean::Item) -> fmt::Result { let deref_type = impl_.impl_.trait_.as_ref().unwrap(); let target = impl_.impl_.items.iter().filter_map(|item| { match item.inner { @@ -2470,12 +2500,12 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl) -> f }).next().expect("Expected associated type binding"); let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target }; match *target { - clean::ResolvedPath { did, .. } => render_assoc_items(w, cx, did, what), + clean::ResolvedPath { did, .. } => render_assoc_items(w, cx, container_item, did, what), _ => { if let Some(prim) = target.primitive_type() { if let Some(c) = cache().primitive_locations.get(&prim) { let did = DefId { krate: *c, index: prim.to_def_index() }; - try!(render_assoc_items(w, cx, did, what)); + try!(render_assoc_items(w, cx, container_item, did, what)); } } Ok(()) @@ -2487,47 +2517,53 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl) -> f // otherwise. If render_header is false, we will avoid rendering static // methods, since they are not accessible for the type implementing `Deref` fn render_impl(w: &mut fmt::Formatter, cx: &Context, i: &Impl, link: AssocItemLink, - render_header: bool) -> fmt::Result { + render_header: bool, outer_version: Option<&str>) -> fmt::Result { if render_header { - try!(write!(w, "

{}

", i.impl_)); + try!(write!(w, "

{}", i.impl_)); + let since = i.stability.as_ref().map(|s| &s.since[..]); + try!(render_stability_since_raw(w, since, outer_version)); + try!(write!(w, "

")); if let Some(ref dox) = i.dox { try!(write!(w, "
{}
", Markdown(dox))); } } fn doctraititem(w: &mut fmt::Formatter, cx: &Context, item: &clean::Item, - link: AssocItemLink, render_static: bool) -> fmt::Result { + link: AssocItemLink, render_static: bool, + outer_version: Option<&str>) -> fmt::Result { let name = item.name.as_ref().unwrap(); match item.inner { clean::MethodItem(..) | clean::TyMethodItem(..) => { // Only render when the method is not static or we allow static methods if !is_static_method(item) || render_static { let id = derive_id(format!("method.{}", name)); - try!(write!(w, "

", id, shortty(item))); - try!(render_assoc_item(w, item, link)); + try!(write!(w, "

", id, shortty(item))); + try!(render_stability_since_raw(w, item.stable_since(), outer_version)); + try!(write!(w, "")); + try!(render_assoc_item(w, item, link)); try!(write!(w, "

\n")); } } clean::TypedefItem(ref tydef, _) => { - let id = derive_id(format!("assoc_type.{}", name)); + let id = derive_id(format!("associatedtype.{}", name)); try!(write!(w, "

", id, shortty(item))); try!(write!(w, "type {} = {}", name, tydef.type_)); try!(write!(w, "

\n")); } clean::AssociatedConstItem(ref ty, ref default) => { - let id = derive_id(format!("assoc_const.{}", name)); + let id = derive_id(format!("associatedconstant.{}", name)); try!(write!(w, "

", id, shortty(item))); try!(assoc_const(w, item, ty, default.as_ref())); try!(write!(w, "

\n")); } clean::ConstantItem(ref c) => { - let id = derive_id(format!("assoc_const.{}", name)); + let id = derive_id(format!("associatedconstant.{}", name)); try!(write!(w, "

", id, shortty(item))); try!(assoc_const(w, item, &c.type_, Some(&c.expr))); try!(write!(w, "

\n")); } clean::AssociatedTypeItem(ref bounds, ref default) => { - let id = derive_id(format!("assoc_type.{}", name)); + let id = derive_id(format!("associatedtype.{}", name)); try!(write!(w, "

", id, shortty(item))); try!(assoc_type(w, item, bounds, default)); try!(write!(w, "

\n")); @@ -2556,7 +2592,7 @@ fn is_static_method(item: &clean::Item) -> bool { try!(write!(w, "
")); for trait_item in &i.impl_.items { - try!(doctraititem(w, cx, trait_item, link, render_header)); + try!(doctraititem(w, cx, trait_item, link, render_header, outer_version)); } fn render_default_items(w: &mut fmt::Formatter, @@ -2564,7 +2600,8 @@ fn render_default_items(w: &mut fmt::Formatter, did: DefId, t: &clean::Trait, i: &clean::Impl, - render_static: bool) -> fmt::Result { + render_static: bool, + outer_version: Option<&str>) -> fmt::Result { for trait_item in &t.items { let n = trait_item.name.clone(); match i.items.iter().find(|m| { m.name == n }) { @@ -2572,7 +2609,8 @@ fn render_default_items(w: &mut fmt::Formatter, None => {} } - try!(doctraititem(w, cx, trait_item, AssocItemLink::GotoSource(did), render_static)); + try!(doctraititem(w, cx, trait_item, AssocItemLink::GotoSource(did), render_static, + outer_version)); } Ok(()) } @@ -2583,7 +2621,7 @@ fn render_default_items(w: &mut fmt::Formatter, // for them work. if let Some(clean::ResolvedPath { did, .. }) = i.impl_.trait_ { if let Some(t) = cache().traits.get(&did) { - try!(render_default_items(w, cx, did, t, &i.impl_, render_header)); + try!(render_default_items(w, cx, did, t, &i.impl_, render_header, outer_version)); } } @@ -2675,6 +2713,7 @@ fn item_macro(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, try!(w.write_str(&highlight::highlight(&t.source, Some("macro"), None))); + try!(render_stability_since_raw(w, it.stable_since(), None)); document(w, cx, it) } @@ -2682,7 +2721,7 @@ fn item_primitive(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, _p: &clean::PrimitiveType) -> fmt::Result { try!(document(w, cx, it)); - render_assoc_items(w, cx, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn get_basic_keywords() -> &'static str {