From 93e51b185a62c4a552e721461f0752f28c08fc53 Mon Sep 17 00:00:00 2001
From: Camelid <camelidcamel@gmail.com>
Date: Fri, 22 Jan 2021 15:02:49 -0800
Subject: [PATCH] rustdoc: Fix visibility of trait and impl items

---
 src/librustdoc/clean/mod.rs    | 21 +++++++++++++++++++--
 src/test/rustdoc/visibility.rs | 32 ++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 8fa60fa7178..a116ed686d9 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1096,7 +1096,10 @@ impl Clean<Item> for hir::TraitItem<'_> {
                     AssocTypeItem(bounds.clean(cx), default.clean(cx))
                 }
             };
-            Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx)
+            let what_rustc_thinks =
+                Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx);
+            // Trait items always inherit the trait's visibility -- we don't want to show `pub`.
+            Item { visibility: Inherited, ..what_rustc_thinks }
         })
     }
 }
@@ -1131,7 +1134,21 @@ impl Clean<Item> for hir::ImplItem<'_> {
                     )
                 }
             };
-            Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx)
+
+            let what_rustc_thinks =
+                Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx);
+            let parent_item = cx.tcx.hir().expect_item(cx.tcx.hir().get_parent_item(self.hir_id));
+            if let hir::ItemKind::Impl(impl_) = &parent_item.kind {
+                if impl_.of_trait.is_some() {
+                    // Trait impl items always inherit the impl's visibility --
+                    // we don't want to show `pub`.
+                    Item { visibility: Inherited, ..what_rustc_thinks }
+                } else {
+                    what_rustc_thinks
+                }
+            } else {
+                panic!("found impl item with non-impl parent {:?}", parent_item);
+            }
         })
     }
 }
diff --git a/src/test/rustdoc/visibility.rs b/src/test/rustdoc/visibility.rs
index 59427693c5a..beb638406c4 100644
--- a/src/test/rustdoc/visibility.rs
+++ b/src/test/rustdoc/visibility.rs
@@ -42,3 +42,35 @@ mod a {
         struct FooBPriv;
     }
 }
+
+// @has 'foo/trait.PubTrait.html' '//pre' 'pub trait PubTrait'
+//
+// @has 'foo/trait.PubTrait.html' '//pre' 'type Type;'
+// @!has 'foo/trait.PubTrait.html' '//pre' 'pub type Type;'
+//
+// @has 'foo/trait.PubTrait.html' '//pre' 'const CONST: usize;'
+// @!has 'foo/trait.PubTrait.html' '//pre' 'pub const CONST: usize;'
+//
+// @has 'foo/trait.PubTrait.html' '//pre' 'fn function();'
+// @!has 'foo/trait.PubTrait.html' '//pre' 'pub fn function();'
+
+pub trait PubTrait {
+    type Type;
+    const CONST: usize;
+    fn function();
+}
+
+// @has 'foo/struct.FooPublic.html' '//code' 'type Type'
+// @!has 'foo/struct.FooPublic.html' '//code' 'pub type Type'
+//
+// @has 'foo/struct.FooPublic.html' '//code' 'const CONST: usize'
+// @!has 'foo/struct.FooPublic.html' '//code' 'pub const CONST: usize'
+//
+// @has 'foo/struct.FooPublic.html' '//code' 'fn function()'
+// @!has 'foo/struct.FooPublic.html' '//code' 'pub fn function()'
+
+impl PubTrait for FooPublic {
+    type Type = usize;
+    const CONST: usize = 0;
+    fn function() {}
+}