]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #39944 - GuillaumeGomez:associated-consts, r=frewsxcv
authorCorey Farwell <coreyf@rwell.org>
Wed, 1 Mar 2017 03:55:28 +0000 (22:55 -0500)
committerGitHub <noreply@github.com>
Wed, 1 Mar 2017 03:55:28 +0000 (22:55 -0500)
Improve associated constant rendering in rustdoc

Before:

<img width="1440" alt="screen shot 2017-02-19 at 00 30 51" src="https://cloud.githubusercontent.com/assets/3050060/23097697/caeed80e-f63a-11e6-98c2-5d27e4efd76d.png">

After:

<img width="1440" alt="screen shot 2017-02-19 at 00 30 39" src="https://cloud.githubusercontent.com/assets/3050060/23097698/cfb4874e-f63a-11e6-80cf-ffbf5c5c6162.png">

cc @SergioBenitez

r? @rust-lang/docs

1  2 
src/librustdoc/clean/mod.rs
src/librustdoc/html/highlight.rs
src/librustdoc/html/render.rs

index 73b82fbad5dfda02aa50b0fb975ddd442c6a7143,215d3d1a8279c6375cdebc732c5160e211a8c260..1294296840ebd75b329bd6df6c81e1309883caf3
@@@ -596,18 -596,14 +596,18 @@@ impl Clean<TyParam> for hir::TyParam 
      }
  }
  
 -impl<'tcx> Clean<TyParam> for ty::TypeParameterDef<'tcx> {
 +impl<'tcx> Clean<TyParam> for ty::TypeParameterDef {
      fn clean(&self, cx: &DocContext) -> TyParam {
          cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx));
          TyParam {
              name: self.name.clean(cx),
              did: self.def_id,
              bounds: vec![], // these are filled in from the where-clauses
 -            default: self.default.clean(cx),
 +            default: if self.has_default {
 +                Some(cx.tcx.item_type(self.def_id).clean(cx))
 +            } else {
 +                None
 +            }
          }
      }
  }
@@@ -969,7 -965,7 +969,7 @@@ impl Clean<Generics> for hir::Generics 
      }
  }
  
 -impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
 +impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
                                      &'a ty::GenericPredicates<'tcx>) {
      fn clean(&self, cx: &DocContext) -> Generics {
          use self::WherePredicate as WP;
@@@ -1163,7 -1159,7 +1163,7 @@@ impl<'a, A: Copy> Clean<FnDecl> for (&'
      }
  }
  
 -impl<'a, 'tcx> Clean<FnDecl> for (DefId, &'a ty::PolyFnSig<'tcx>) {
 +impl<'a, 'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
      fn clean(&self, cx: &DocContext) -> FnDecl {
          let (did, sig) = *self;
          let mut names = if cx.tcx.hir.as_local_node_id(did).is_some() {
@@@ -1352,8 -1348,11 +1352,8 @@@ impl<'tcx> Clean<Item> for ty::Associat
              ty::AssociatedKind::Method => {
                  let generics = (cx.tcx.item_generics(self.def_id),
                                  &cx.tcx.item_predicates(self.def_id)).clean(cx);
 -                let fty = match cx.tcx.item_type(self.def_id).sty {
 -                    ty::TyFnDef(_, _, f) => f,
 -                    _ => unreachable!()
 -                };
 -                let mut decl = (self.def_id, &fty.sig).clean(cx);
 +                let sig = cx.tcx.item_type(self.def_id).fn_sig();
 +                let mut decl = (self.def_id, sig).clean(cx);
  
                  if self.method_has_self_argument {
                      let self_ty = match self.container {
                          }
                          ty::TraitContainer(_) => cx.tcx.mk_self_type()
                      };
 -                    let self_arg_ty = *fty.sig.input(0).skip_binder();
 +                    let self_arg_ty = *sig.input(0).skip_binder();
                      if self_arg_ty == self_ty {
                          decl.inputs.values[0].type_ = Generic(String::from("Self"));
                      } else if let ty::TyRef(_, mt) = self_arg_ty.sty {
                  };
                  if provided {
                      MethodItem(Method {
 -                        unsafety: fty.unsafety,
 +                        unsafety: sig.unsafety(),
                          generics: generics,
                          decl: decl,
 -                        abi: fty.abi,
 +                        abi: sig.abi(),
  
                          // trait methods canot (currently, at least) be const
                          constness: hir::Constness::NotConst,
                      })
                  } else {
                      TyMethodItem(TyMethod {
 -                        unsafety: fty.unsafety,
 +                        unsafety: sig.unsafety(),
                          generics: generics,
                          decl: decl,
 -                        abi: fty.abi,
 +                        abi: sig.abi(),
                      })
                  }
              }
@@@ -1476,7 -1475,7 +1476,7 @@@ pub struct PolyTrait 
  /// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
  /// type out of the AST/TyCtxt given one of these, if more information is needed. Most importantly
  /// it does not preserve mutability or boxes.
- #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
+ #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq)]
  pub enum Type {
      /// structs/enums/traits (most that'd be an hir::TyPath)
      ResolvedPath {
@@@ -1769,7 -1768,7 +1769,7 @@@ impl Clean<Type> for hir::Ty 
              }
              TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => {
                  let mut def = Def::Err;
 -                if let Some(ty) = cx.hir_ty_to_ty.get(&self.id) {
 +                if let Some(ty) = cx.tcx.ast_ty_to_ty_cache.borrow().get(&self.id) {
                      if let ty::TyProjection(proj) = ty.sty {
                          def = Def::Trait(proj.trait_ref.def_id);
                      }
@@@ -1831,16 -1830,16 +1831,16 @@@ impl<'tcx> Clean<Type> for ty::Ty<'tcx
                  mutability: mt.mutbl.clean(cx),
                  type_: box mt.ty.clean(cx),
              },
 -            ty::TyFnDef(.., ref fty) |
 -            ty::TyFnPtr(ref fty) => BareFunction(box BareFunctionDecl {
 -                unsafety: fty.unsafety,
 +            ty::TyFnDef(.., sig) |
 +            ty::TyFnPtr(sig) => BareFunction(box BareFunctionDecl {
 +                unsafety: sig.unsafety(),
                  generics: Generics {
                      lifetimes: Vec::new(),
                      type_params: Vec::new(),
                      where_predicates: Vec::new()
                  },
 -                decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), &fty.sig).clean(cx),
 -                abi: fty.abi,
 +                decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
 +                abi: sig.abi(),
              }),
              ty::TyAdt(def, substs) => {
                  let did = def.did;
index 2c15dd923237fe840362c352c72bac70d3756eca,46db2d538a6529ee4775e909095191aed92efeda..0dafc4225a3210653e6d9b445914c825db8c9a35
@@@ -144,12 -144,12 +144,12 @@@ impl<U: Write> Writer for U 
                            -> io::Result<()> {
          match klass {
              Class::None => write!(self, "{}", text),
-             klass => write!(self, "<span class='{}'>{}</span>", klass.rustdoc_class(), text),
+             klass => write!(self, "<span class=\"{}\">{}</span>", klass.rustdoc_class(), text),
          }
      }
  
      fn enter_span(&mut self, klass: Class) -> io::Result<()> {
-         write!(self, "<span class='{}'>", klass.rustdoc_class())
+         write!(self, "<span class=\"{}\">", klass.rustdoc_class())
      }
  
      fn exit_span(&mut self) -> io::Result<()> {
@@@ -315,7 -315,7 +315,7 @@@ impl<'a> Classifier<'a> 
              token::Lifetime(..) => Class::Lifetime,
  
              token::Underscore | token::Eof | token::Interpolated(..) |
 -            token::MatchNt(..) | token::SubstNt(..) | token::Tilde | token::At => Class::None,
 +            token::SubstNt(..) | token::Tilde | token::At => Class::None,
          };
  
          // Anything that didn't return above is the simple case where we the
@@@ -363,7 -363,7 +363,7 @@@ fn write_header(class: Option<&str>
      if let Some(id) = id {
          write!(out, "id='{}' ", id)?;
      }
-     write!(out, "class='rust {}'>\n", class.unwrap_or(""))
+     write!(out, "class=\"rust {}\">\n", class.unwrap_or(""))
  }
  
  fn write_footer(out: &mut Write) -> io::Result<()> {
index bb39c8c4f22ffb53e0ec4680d1f0c91d99c72da1,ead913b57be50dd1e89a6cca1465b167f237f050..44f71d8952985b0098e482d561dad83d960969da
@@@ -1547,7 -1547,7 +1547,7 @@@ impl<'a> fmt::Display for Item<'a> 
                         component)?;
              }
          }
-         write!(fmt, "<a class='{}' href=''>{}</a>",
+         write!(fmt, "<a class=\"{}\" href=''>{}</a>",
                 self.item.type_(), self.item.name.as_ref().unwrap())?;
  
          write!(fmt, "</span>")?; // in-band
@@@ -1654,9 -1654,35 +1654,35 @@@ fn document_short(w: &mut fmt::Formatte
      Ok(())
  }
  
+ fn md_render_assoc_item(item: &clean::Item) -> String {
+     match item.inner {
+         clean::AssociatedConstItem(ref ty, ref default) => {
+             if let Some(default) = default.as_ref() {
+                 format!("```\n{}: {:?} = {}\n```\n\n", item.name.as_ref().unwrap(), ty, default)
+             } else {
+                 format!("```\n{}: {:?}\n```\n\n", item.name.as_ref().unwrap(), ty)
+             }
+         }
+         _ => String::new(),
+     }
+ }
+ fn get_doc_value(item: &clean::Item) -> Option<&str> {
+     let x = item.doc_value();
+     if x.is_none() {
+         match item.inner {
+             clean::AssociatedConstItem(_, _) => Some(""),
+             _ => None,
+         }
+     } else {
+         x
+     }
+ }
  fn document_full(w: &mut fmt::Formatter, item: &clean::Item) -> fmt::Result {
-     if let Some(s) = item.doc_value() {
-         write!(w, "<div class='docblock'>{}</div>", Markdown(s))?;
+     if let Some(s) = get_doc_value(item) {
+         write!(w, "<div class='docblock'>{}</div>",
+                Markdown(&format!("{}{}", md_render_assoc_item(item), s)))?;
      }
      Ok(())
  }
@@@ -1817,7 -1843,7 +1843,7 @@@ fn item_module(w: &mut fmt::Formatter, 
                  let doc_value = myitem.doc_value().unwrap_or("");
                  write!(w, "
                         <tr class='{stab} module-item'>
-                            <td><a class='{class}' href='{href}'
+                            <td><a class=\"{class}\" href=\"{href}\"
                                    title='{title_type} {title}'>{name}</a>{unsafety_flag}</td>
                             <td class='docblock-short'>
                                 {stab_docs} {docs}
@@@ -1878,7 -1904,7 +1904,7 @@@ fn short_stability(item: &clean::Item, 
                                              &cx.shared.issue_tracker_base_url,
                                              stab.issue) {
                      (true, &Some(ref tracker_url), Some(issue_no)) if issue_no > 0 =>
 -                        format!(" (<code>{}</code> <a href=\"{}{}\">#{}</a>)",
 +                        format!(" (<code>{} </code><a href=\"{}{}\">#{}</a>)",
                                  Escape(&stab.feature), tracker_url, issue_no, issue_no),
                      (false, &Some(ref tracker_url), Some(issue_no)) if issue_no > 0 =>
                          format!(" (<a href=\"{}{}\">#{}</a>)", Escape(&tracker_url), issue_no,
                  if stab.unstable_reason.is_empty() {
                      stability.push(format!("<div class='stab unstable'>\
                                              <span class=microscope>🔬</span> \
 -                                            This is a nightly-only experimental API. &nbsp;{}\
 +                                            This is a nightly-only experimental API. {}\
                                              </div>",
 -                                   unstable_extra));
 +                                           unstable_extra));
                  } else {
                      let text = format!("<summary><span class=microscope>🔬</span> \
 -                                        This is a nightly-only experimental API. &nbsp;{}\
 +                                        This is a nightly-only experimental API. {}\
                                          </summary>{}",
                                         unstable_extra, MarkdownHtml(&stab.unstable_reason));
                      stability.push(format!("<div class='stab unstable'><details>{}</details></div>",
@@@ -2215,16 -2241,12 +2241,12 @@@ fn naive_assoc_href(it: &clean::Item, l
  fn assoc_const(w: &mut fmt::Formatter,
                 it: &clean::Item,
                 ty: &clean::Type,
-                default: Option<&String>,
+                _default: Option<&String>,
                 link: AssocItemLink) -> fmt::Result {
-     write!(w, "const <a href='{}' class='constant'>{}</a>",
+     write!(w, "const <a href='{}' class=\"constant\"><b>{}</b></a>: {}",
             naive_assoc_href(it, link),
-            it.name.as_ref().unwrap())?;
-     write!(w, ": {}", ty)?;
-     if let Some(default) = default {
-         write!(w, " = {}", Escape(default))?;
-     }
+            it.name.as_ref().unwrap(),
+            ty)?;
      Ok(())
  }
  
@@@ -2232,7 -2254,7 +2254,7 @@@ fn assoc_type(w: &mut fmt::Formatter, i
                bounds: &Vec<clean::TyParamBound>,
                default: Option<&clean::Type>,
                link: AssocItemLink) -> fmt::Result {
-     write!(w, "type <a href='{}' class='type'>{}</a>",
+     write!(w, "type <a href='{}' class=\"type\">{}</a>",
             naive_assoc_href(it, link),
             it.name.as_ref().unwrap())?;
      if !bounds.is_empty() {
@@@ -2375,7 -2397,7 +2397,7 @@@ fn item_struct(w: &mut fmt::Formatter, 
                  let ns_id = derive_id(format!("{}.{}",
                                                field.name.as_ref().unwrap(),
                                                ItemType::StructField.name_space()));
-                 write!(w, "<span id='{id}' class='{item_type}'>
+                 write!(w, "<span id='{id}' class=\"{item_type}\">
                             <span id='{ns_id}' class='invisible'>
                             <code>{name}: {ty}</code>
                             </span></span>",
@@@ -2417,7 -2439,7 +2439,7 @@@ fn item_union(w: &mut fmt::Formatter, c
      if fields.peek().is_some() {
          write!(w, "<h2 class='fields'>Fields</h2>")?;
          for (field, ty) in fields {
-             write!(w, "<span id='{shortty}.{name}' class='{shortty}'><code>{name}: {ty}</code>
+             write!(w, "<span id='{shortty}.{name}' class=\"{shortty}\"><code>{name}: {ty}</code>
                         </span>",
                     shortty = ItemType::StructField,
                     name = field.name.as_ref().unwrap(),
@@@ -2902,7 -2924,7 +2924,7 @@@ fn render_impl(w: &mut fmt::Formatter, 
                  if render_method_item {
                      let id = derive_id(format!("{}.{}", item_type, name));
                      let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
-                     write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
+                     write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?;
                      write!(w, "<span id='{}' class='invisible'>", ns_id)?;
                      write!(w, "<code>")?;
                      render_assoc_item(w, item, link.anchor(&id), ItemType::Impl)?;
              clean::TypedefItem(ref tydef, _) => {
                  let id = derive_id(format!("{}.{}", ItemType::AssociatedType, name));
                  let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
-                 write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
+                 write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?;
                  write!(w, "<span id='{}' class='invisible'><code>", ns_id)?;
                  assoc_type(w, item, &Vec::new(), Some(&tydef.type_), link.anchor(&id))?;
                  write!(w, "</code></span></h4>\n")?;
              clean::AssociatedConstItem(ref ty, ref default) => {
                  let id = derive_id(format!("{}.{}", item_type, name));
                  let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
-                 write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
+                 write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?;
                  write!(w, "<span id='{}' class='invisible'><code>", ns_id)?;
                  assoc_const(w, item, ty, default.as_ref(), link.anchor(&id))?;
                  write!(w, "</code></span></h4>\n")?;
              clean::ConstantItem(ref c) => {
                  let id = derive_id(format!("{}.{}", item_type, name));
                  let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
-                 write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
+                 write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?;
                  write!(w, "<span id='{}' class='invisible'><code>", ns_id)?;
                  assoc_const(w, item, &c.type_, Some(&c.expr), link.anchor(&id))?;
                  write!(w, "</code></span></h4>\n")?;
              clean::AssociatedTypeItem(ref bounds, ref default) => {
                  let id = derive_id(format!("{}.{}", item_type, name));
                  let ns_id = derive_id(format!("{}.{}", name, item_type.name_space()));
-                 write!(w, "<h4 id='{}' class='{}'>", id, item_type)?;
+                 write!(w, "<h4 id='{}' class=\"{}\">", id, item_type)?;
                  write!(w, "<span id='{}' class='invisible'><code>", ns_id)?;
                  assoc_type(w, item, bounds, default.as_ref(), link.anchor(&id))?;
                  write!(w, "</code></span></h4>\n")?;
                          // We need the stability of the item from the trait
                          // because impls can't have a stability.
                          document_stability(w, cx, it)?;
-                         if item.doc_value().is_some() {
+                         if get_doc_value(item).is_some() {
                              document_full(w, item)?;
                          } else {
                              // In case the item isn't documented,