about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2021-02-12 19:32:07 +0900
committerGitHub <noreply@github.com>2021-02-12 19:32:07 +0900
commit327762f0885c1c291e8f8dda671e1efd2b7030d6 (patch)
tree9997ff1d990f4af954ae6f4abdc34fa6cd90b641 /src
parent0b6876cbe7856f8896a7939ddba97f22c1a37492 (diff)
parent089ee27dd0ef2a639647cddecb2ea332c8d02bac (diff)
downloadrust-327762f0885c1c291e8f8dda671e1efd2b7030d6.tar.gz
rust-327762f0885c1c291e8f8dda671e1efd2b7030d6.zip
Rollup merge of #81831 - LeSeulArtichaut:81289-mut-arg, r=camelid
Don't display `mut` in arguments for functions documentation

Fixes #81289 by reverting #80799, as requested in https://github.com/rust-lang/rust/pull/81328#issuecomment-766364413.
Supersedes #81328.
r? ``@camelid`` cc ``@jyn514``
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/clean/utils.rs67
-rw-r--r--src/test/rustdoc/mut-params.rs18
-rw-r--r--src/test/rustdoc/range-arg-pattern.rs2
4 files changed, 87 insertions, 2 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 331bb2a73f9..4d0d7e75aec 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -961,7 +961,7 @@ impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], hir::BodyId) {
                 .iter()
                 .enumerate()
                 .map(|(i, ty)| Argument {
-                    name: Symbol::intern(&rustc_hir_pretty::param_to_string(&body.params[i])),
+                    name: name_from_pat(&body.params[i].pat),
                     type_: ty.clean(cx),
                 })
                 .collect(),
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 8f005be7cf7..8640e3c3244 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -195,6 +195,25 @@ crate fn strip_path(path: &Path) -> Path {
     Path { global: path.global, res: path.res, segments }
 }
 
+crate fn qpath_to_string(p: &hir::QPath<'_>) -> String {
+    let segments = match *p {
+        hir::QPath::Resolved(_, ref path) => &path.segments,
+        hir::QPath::TypeRelative(_, ref segment) => return segment.ident.to_string(),
+        hir::QPath::LangItem(lang_item, ..) => return lang_item.name().to_string(),
+    };
+
+    let mut s = String::new();
+    for (i, seg) in segments.iter().enumerate() {
+        if i > 0 {
+            s.push_str("::");
+        }
+        if seg.ident.name != kw::PathRoot {
+            s.push_str(&seg.ident.as_str());
+        }
+    }
+    s
+}
+
 crate fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec<Item>) {
     let tcx = cx.tcx;
 
@@ -232,6 +251,54 @@ impl ToSource for rustc_span::Span {
     }
 }
 
+crate fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
+    use rustc_hir::*;
+    debug!("trying to get a name from pattern: {:?}", p);
+
+    Symbol::intern(&match p.kind {
+        PatKind::Wild => return kw::Underscore,
+        PatKind::Binding(_, _, ident, _) => return ident.name,
+        PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p),
+        PatKind::Struct(ref name, ref fields, etc) => format!(
+            "{} {{ {}{} }}",
+            qpath_to_string(name),
+            fields
+                .iter()
+                .map(|fp| format!("{}: {}", fp.ident, name_from_pat(&fp.pat)))
+                .collect::<Vec<String>>()
+                .join(", "),
+            if etc { ", .." } else { "" }
+        ),
+        PatKind::Or(ref pats) => pats
+            .iter()
+            .map(|p| name_from_pat(&**p).to_string())
+            .collect::<Vec<String>>()
+            .join(" | "),
+        PatKind::Tuple(ref elts, _) => format!(
+            "({})",
+            elts.iter()
+                .map(|p| name_from_pat(&**p).to_string())
+                .collect::<Vec<String>>()
+                .join(", ")
+        ),
+        PatKind::Box(ref p) => return name_from_pat(&**p),
+        PatKind::Ref(ref p, _) => return name_from_pat(&**p),
+        PatKind::Lit(..) => {
+            warn!(
+                "tried to get argument name from PatKind::Lit, which is silly in function arguments"
+            );
+            return Symbol::intern("()");
+        }
+        PatKind::Range(..) => return kw::Underscore,
+        PatKind::Slice(ref begin, ref mid, ref end) => {
+            let begin = begin.iter().map(|p| name_from_pat(&**p).to_string());
+            let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter();
+            let end = end.iter().map(|p| name_from_pat(&**p).to_string());
+            format!("[{}]", begin.chain(mid).chain(end).collect::<Vec<_>>().join(", "))
+        }
+    })
+}
+
 crate fn print_const(cx: &DocContext<'_>, n: &'tcx ty::Const<'_>) -> String {
     match n.val {
         ty::ConstKind::Unevaluated(def, _, promoted) => {
diff --git a/src/test/rustdoc/mut-params.rs b/src/test/rustdoc/mut-params.rs
new file mode 100644
index 00000000000..1ef7e304fa2
--- /dev/null
+++ b/src/test/rustdoc/mut-params.rs
@@ -0,0 +1,18 @@
+// Rustdoc shouldn't display `mut` in function arguments, which are
+// implementation details. Regression test for #81289.
+
+#![crate_name = "foo"]
+
+pub struct Foo;
+
+// @count foo/struct.Foo.html '//*[@class="impl-items"]//*[@class="method"]' 2
+// @!has - '//*[@class="impl-items"]//*[@class="method"]' 'mut'
+impl Foo {
+    pub fn foo(mut self) {}
+
+    pub fn bar(mut bar: ()) {}
+}
+
+// @count foo/fn.baz.html '//*[@class="rust fn"]' 1
+// @!has - '//*[@class="rust fn"]' 'mut'
+pub fn baz(mut foo: Foo) {}
diff --git a/src/test/rustdoc/range-arg-pattern.rs b/src/test/rustdoc/range-arg-pattern.rs
index f4cc36b1055..c08faaad0ec 100644
--- a/src/test/rustdoc/range-arg-pattern.rs
+++ b/src/test/rustdoc/range-arg-pattern.rs
@@ -1,5 +1,5 @@
 #![crate_name = "foo"]
 
 // @has foo/fn.f.html
-// @has - '//*[@class="rust fn"]' 'pub fn f(0u8 ...255: u8)'
+// @has - '//*[@class="rust fn"]' 'pub fn f(_: u8)'
 pub fn f(0u8...255: u8) {}