From 6ee9109c8b1eb170b7fb6fac6d248801dcd42817 Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Fri, 23 May 2014 17:13:44 -0700
Subject: [PATCH] rustdoc: Inline argument names of foreign methods

---
 src/librustc/metadata/common.rs  |  3 +++
 src/librustc/metadata/csearch.rs |  7 +++++++
 src/librustc/metadata/decoder.rs | 15 +++++++++++++++
 src/librustc/metadata/encoder.rs | 15 +++++++++++++++
 src/librustdoc/clean.rs          | 18 ++++++++++++++----
 5 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs
index f30d6119339..c798118bbd0 100644
--- a/src/librustc/metadata/common.rs
+++ b/src/librustc/metadata/common.rs
@@ -206,6 +206,9 @@ pub static tag_crate_triple: uint = 0x66;
 
 pub static tag_dylib_dependency_formats: uint = 0x67;
 
+pub static tag_method_argument_names: uint = 0x8e;
+pub static tag_method_argument_name: uint = 0x8f;
+
 #[deriving(Clone, Show)]
 pub struct LinkMeta {
     pub crateid: CrateId,
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index efe3633195e..d7f603d1909 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -306,3 +306,10 @@ pub fn get_missing_lang_items(cstore: &cstore::CStore, cnum: ast::CrateNum)
     let cdata = cstore.get_crate_data(cnum);
     decoder::get_missing_lang_items(&*cdata)
 }
+
+pub fn get_method_arg_names(cstore: &cstore::CStore, did: ast::DefId)
+    -> Vec<StrBuf>
+{
+    let cdata = cstore.get_crate_data(did.krate);
+    decoder::get_method_arg_names(&*cdata, did.node)
+}
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index 83b24d882e5..26149785653 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -1309,3 +1309,18 @@ pub fn get_missing_lang_items(cdata: Cmd)
     });
     return result;
 }
+
+pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec<StrBuf> {
+    let mut ret = Vec::new();
+    let method_doc = lookup_item(id, cdata.data());
+    match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
+        Some(args_doc) => {
+            reader::tagged_docs(args_doc, tag_method_argument_name, |name_doc| {
+                ret.push(name_doc.as_str_slice().to_strbuf());
+                true
+            });
+        }
+        None => {}
+    }
+    return ret;
+}
diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs
index bd333a5afe0..941977f6d16 100644
--- a/src/librustc/metadata/encoder.rs
+++ b/src/librustc/metadata/encoder.rs
@@ -774,6 +774,21 @@ fn encode_info_for_method(ecx: &EncodeContext,
         } else {
             encode_symbol(ecx, ebml_w, m.def_id.node);
         }
+
+        ebml_w.start_tag(tag_method_argument_names);
+        for arg in ast_method.decl.inputs.iter() {
+            ebml_w.start_tag(tag_method_argument_name);
+            match arg.pat.node {
+                ast::PatIdent(_, ref name, _) => {
+                    let name = name.segments.last().unwrap().identifier;
+                    let name = token::get_ident(name);
+                    ebml_w.writer.write(name.get().as_bytes());
+                }
+                _ => {}
+            }
+            ebml_w.end_tag();
+        }
+        ebml_w.end_tag();
     }
 
     ebml_w.end_tag();
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index 94ccd3ac40e..6e3186eda4c 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -488,7 +488,7 @@ impl Clean<Option<Vec<TyParamBound>>> for ty::substs {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, Eq)]
 pub struct Lifetime(String);
 
 impl Lifetime {
@@ -629,7 +629,7 @@ impl Clean<Item> for ast::TypeMethod {
     }
 }
 
-#[deriving(Clone, Encodable, Decodable)]
+#[deriving(Clone, Encodable, Decodable, Eq)]
 pub enum SelfTy {
     SelfStatic,
     SelfValue,
@@ -868,6 +868,16 @@ impl Clean<TraitMethod> for ty::Method {
                 (s, sig)
             }
         };
+        let mut names = csearch::get_method_arg_names(&tcx.sess.cstore,
+                                                      self.def_id).move_iter();
+        if self_ != SelfStatic {
+            names.next();
+        }
+        let mut decl = sig.clean();
+        for (name, slot) in names.zip(decl.inputs.values.mut_iter()) {
+            slot.name = name;
+        }
+
         m(Item {
             name: Some(self.ident.clean()),
             visibility: Some(ast::Inherited),
@@ -878,7 +888,7 @@ impl Clean<TraitMethod> for ty::Method {
                 fn_style: self.fty.fn_style,
                 generics: self.generics.clean(),
                 self_: self_,
-                decl: sig.clean(),
+                decl: decl,
             })
         })
     }
@@ -1437,7 +1447,7 @@ impl Clean<Item> for doctree::Static {
     }
 }
 
-#[deriving(Show, Clone, Encodable, Decodable)]
+#[deriving(Show, Clone, Encodable, Decodable, Eq)]
 pub enum Mutability {
     Mutable,
     Immutable,