From c8b16cdbd0f06c66467c082b9d3e190255fa295d Mon Sep 17 00:00:00 2001
From: Dennis Hamester <dennis.hamester@gmail.com>
Date: Wed, 8 Jul 2020 07:39:49 +0200
Subject: [PATCH 1/4] rustdoc: Allow linking from private items to private
 types

Fixes #74134

After PR #72771 this would trigger an intra_doc_link_resolution_failure warning
when rustdoc is invoked without --document-private-items. Links from private
items to private types are however never actually generated in that case and
thus shouldn't produce a warning. These links are in fact a very useful tool to
document crate internals.

Tests are added for all 4 combinations of public/private items and link
targets. Test 1 is the case mentioned above and fails without this commit. Tests
2 - 4 passed before already but are added nonetheless to prevent regressions.
---
 src/librustdoc/passes/collect_intra_doc_links.rs |  1 +
 src/test/rustdoc/issue-74134-1.rs                | 10 ++++++++++
 src/test/rustdoc/issue-74134-2.rs                | 11 +++++++++++
 src/test/rustdoc/issue-74134-3.rs                | 11 +++++++++++
 src/test/rustdoc/issue-74134-4.rs                | 11 +++++++++++
 5 files changed, 44 insertions(+)
 create mode 100644 src/test/rustdoc/issue-74134-1.rs
 create mode 100644 src/test/rustdoc/issue-74134-2.rs
 create mode 100644 src/test/rustdoc/issue-74134-3.rs
 create mode 100644 src/test/rustdoc/issue-74134-4.rs

diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index f1d1bf439f171..86f94af0c6e31 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -796,6 +796,7 @@ impl<'a, 'tcx> DocFolder for LinkCollector<'a, 'tcx> {
 
                     let hir_id = self.cx.tcx.hir().as_local_hir_id(local);
                     if !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_id)
+                        && (item.visibility == Visibility::Public)
                         && !self.cx.render_options.document_private
                     {
                         let item_name = item.name.as_deref().unwrap_or("<unknown>");
diff --git a/src/test/rustdoc/issue-74134-1.rs b/src/test/rustdoc/issue-74134-1.rs
new file mode 100644
index 0000000000000..72d38638a794c
--- /dev/null
+++ b/src/test/rustdoc/issue-74134-1.rs
@@ -0,0 +1,10 @@
+#![deny(intra_doc_link_resolution_failure)]
+
+// Linking from a private item to a private type is fine without --document-private-items.
+
+struct Private;
+
+pub struct Public {
+    /// [`Private`]
+    private: Private,
+}
diff --git a/src/test/rustdoc/issue-74134-2.rs b/src/test/rustdoc/issue-74134-2.rs
new file mode 100644
index 0000000000000..f665e360b4982
--- /dev/null
+++ b/src/test/rustdoc/issue-74134-2.rs
@@ -0,0 +1,11 @@
+// compile-flags: --document-private-items
+#![deny(intra_doc_link_resolution_failure)]
+
+// Linking from a private item to a private type is fine with --document-private-items.
+
+struct Private;
+
+pub struct Public {
+    /// [`Private`]
+    private: Private,
+}
diff --git a/src/test/rustdoc/issue-74134-3.rs b/src/test/rustdoc/issue-74134-3.rs
new file mode 100644
index 0000000000000..b2709ecdaddda
--- /dev/null
+++ b/src/test/rustdoc/issue-74134-3.rs
@@ -0,0 +1,11 @@
+// should-fail
+#![deny(intra_doc_link_resolution_failure)]
+
+// Linking from a public item to a private type fails without --document-private-items.
+
+struct Private;
+
+pub struct Public {
+    /// [`Private`]
+    pub public: u32,
+}
diff --git a/src/test/rustdoc/issue-74134-4.rs b/src/test/rustdoc/issue-74134-4.rs
new file mode 100644
index 0000000000000..efff74f279721
--- /dev/null
+++ b/src/test/rustdoc/issue-74134-4.rs
@@ -0,0 +1,11 @@
+// compile-flags: --document-private-items
+#![deny(intra_doc_link_resolution_failure)]
+
+// Linking from a public item to a private type is fine with --document-private-items.
+
+struct Private;
+
+pub struct Public {
+    /// [`Private`]
+    pub public: u32,
+}

From 689e360d8273ed13e433ce3e7ae1046e33894234 Mon Sep 17 00:00:00 2001
From: Dennis Hamester <dennis.hamester@gmail.com>
Date: Sat, 11 Jul 2020 09:26:26 +0200
Subject: [PATCH 2/4] test: rustdoc-ui: Add issue-74134, replacing
 test/rustdoc/issue-74134-*

As per the discussion in PR #74147, the 4 individual tests are replaced by a
single one.

The test is expanded to cover all 4 public/private cases, each with and without
--document-private-items.
---
 src/test/rustdoc-ui/issue-74134.public.stderr | 10 +++++++
 src/test/rustdoc-ui/issue-74134.rs            | 26 +++++++++++++++++++
 src/test/rustdoc/issue-74134-1.rs             | 10 -------
 src/test/rustdoc/issue-74134-2.rs             | 11 --------
 src/test/rustdoc/issue-74134-3.rs             | 11 --------
 src/test/rustdoc/issue-74134-4.rs             | 11 --------
 6 files changed, 36 insertions(+), 43 deletions(-)
 create mode 100644 src/test/rustdoc-ui/issue-74134.public.stderr
 create mode 100644 src/test/rustdoc-ui/issue-74134.rs
 delete mode 100644 src/test/rustdoc/issue-74134-1.rs
 delete mode 100644 src/test/rustdoc/issue-74134-2.rs
 delete mode 100644 src/test/rustdoc/issue-74134-3.rs
 delete mode 100644 src/test/rustdoc/issue-74134-4.rs

diff --git a/src/test/rustdoc-ui/issue-74134.public.stderr b/src/test/rustdoc-ui/issue-74134.public.stderr
new file mode 100644
index 0000000000000..03f95f19d326e
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-74134.public.stderr
@@ -0,0 +1,10 @@
+warning: `[PrivateType]` public documentation for `public_item` links to a private item
+  --> $DIR/issue-74134.rs:19:10
+   |
+LL |     /// [`PrivateType`]
+   |          ^^^^^^^^^^^^^ this item is private
+   |
+   = note: `#[warn(intra_doc_link_resolution_failure)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/src/test/rustdoc-ui/issue-74134.rs b/src/test/rustdoc-ui/issue-74134.rs
new file mode 100644
index 0000000000000..d0747817580da
--- /dev/null
+++ b/src/test/rustdoc-ui/issue-74134.rs
@@ -0,0 +1,26 @@
+// revisions: public private
+// [private]compile-flags: --document-private-items
+// check-pass
+
+// There are 4 cases here:
+// 1. public item  -> public type:  no warning
+// 2. public item  -> private type: warning, if --document-private-items is not passed
+// 3. private item -> public type:  no warning
+// 4. private item -> private type: no warning
+// All 4 cases are tested with and without --document-private-items.
+//
+// Case 4 without --document-private-items is the one described in issue #74134.
+
+struct PrivateType;
+pub struct PublicType;
+
+pub struct Public {
+    /// [`PublicType`]
+    /// [`PrivateType`]
+    //[public]~^ WARNING `[PrivateType]` public documentation for `public_item` links to a private item
+    pub public_item: u32,
+
+    /// [`PublicType`]
+    /// [`PrivateType`]
+    private_item: u32,
+}
diff --git a/src/test/rustdoc/issue-74134-1.rs b/src/test/rustdoc/issue-74134-1.rs
deleted file mode 100644
index 72d38638a794c..0000000000000
--- a/src/test/rustdoc/issue-74134-1.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-#![deny(intra_doc_link_resolution_failure)]
-
-// Linking from a private item to a private type is fine without --document-private-items.
-
-struct Private;
-
-pub struct Public {
-    /// [`Private`]
-    private: Private,
-}
diff --git a/src/test/rustdoc/issue-74134-2.rs b/src/test/rustdoc/issue-74134-2.rs
deleted file mode 100644
index f665e360b4982..0000000000000
--- a/src/test/rustdoc/issue-74134-2.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// compile-flags: --document-private-items
-#![deny(intra_doc_link_resolution_failure)]
-
-// Linking from a private item to a private type is fine with --document-private-items.
-
-struct Private;
-
-pub struct Public {
-    /// [`Private`]
-    private: Private,
-}
diff --git a/src/test/rustdoc/issue-74134-3.rs b/src/test/rustdoc/issue-74134-3.rs
deleted file mode 100644
index b2709ecdaddda..0000000000000
--- a/src/test/rustdoc/issue-74134-3.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// should-fail
-#![deny(intra_doc_link_resolution_failure)]
-
-// Linking from a public item to a private type fails without --document-private-items.
-
-struct Private;
-
-pub struct Public {
-    /// [`Private`]
-    pub public: u32,
-}
diff --git a/src/test/rustdoc/issue-74134-4.rs b/src/test/rustdoc/issue-74134-4.rs
deleted file mode 100644
index efff74f279721..0000000000000
--- a/src/test/rustdoc/issue-74134-4.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// compile-flags: --document-private-items
-#![deny(intra_doc_link_resolution_failure)]
-
-// Linking from a public item to a private type is fine with --document-private-items.
-
-struct Private;
-
-pub struct Public {
-    /// [`Private`]
-    pub public: u32,
-}

From 97048595e1e7bf3fc270ecf14ccaaac4cc71a241 Mon Sep 17 00:00:00 2001
From: Dennis Hamester <dennis.hamester@gmail.com>
Date: Sat, 11 Jul 2020 10:02:18 +0200
Subject: [PATCH 3/4] test: rustdoc-ui: Expand issue-74134 to cover types in a
 private module

---
 src/test/rustdoc-ui/issue-74134.rs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/test/rustdoc-ui/issue-74134.rs b/src/test/rustdoc-ui/issue-74134.rs
index d0747817580da..ad6ace43071a3 100644
--- a/src/test/rustdoc-ui/issue-74134.rs
+++ b/src/test/rustdoc-ui/issue-74134.rs
@@ -24,3 +24,18 @@ pub struct Public {
     /// [`PrivateType`]
     private_item: u32,
 }
+
+// The following cases are identical to the ones above, except that they are in a private
+// module. Thus they all fall into cases 3 and 4 and should not produce a warning.
+
+mod private {
+    pub struct Public {
+        /// [`super::PublicType`]
+        /// [`super::PrivateType`]
+        pub public_item: u32,
+
+        /// [`super::PublicType`]
+        /// [`super::PrivateType`]
+        private_item: u32,
+    }
+}

From 87895251ea372a8a776a229c45dd703b4e5b22eb Mon Sep 17 00:00:00 2001
From: Dennis Hamester <dennis.hamester@gmail.com>
Date: Sat, 11 Jul 2020 10:31:27 +0200
Subject: [PATCH 4/4] test: rustdoc-ui: issue-74134: Shorten a too long line

---
 src/test/rustdoc-ui/issue-74134.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/test/rustdoc-ui/issue-74134.rs b/src/test/rustdoc-ui/issue-74134.rs
index ad6ace43071a3..d561c2dd89015 100644
--- a/src/test/rustdoc-ui/issue-74134.rs
+++ b/src/test/rustdoc-ui/issue-74134.rs
@@ -17,7 +17,7 @@ pub struct PublicType;
 pub struct Public {
     /// [`PublicType`]
     /// [`PrivateType`]
-    //[public]~^ WARNING `[PrivateType]` public documentation for `public_item` links to a private item
+    //[public]~^ WARNING public documentation for `public_item` links to a private
     pub public_item: u32,
 
     /// [`PublicType`]