about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-01-13 00:41:11 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-01-13 00:41:11 +0300
commitf8028b0b6c3c5c1d6498cf780366641a7c047abf (patch)
treed4ad65f7a547496f7bf791317eae370f519e675b
parentd6525ef539a04cb43de40080bdabc5f2f5a4a197 (diff)
downloadrust-f8028b0b6c3c5c1d6498cf780366641a7c047abf.tar.gz
rust-f8028b0b6c3c5c1d6498cf780366641a7c047abf.zip
privacy: Fix private-in-public check for existential types
-rw-r--r--src/librustc_privacy/lib.rs11
-rw-r--r--src/test/ui/privacy/private-in-public-existential.rs15
2 files changed, 23 insertions, 3 deletions
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 5015ed027cc..4890369e13f 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -48,7 +48,7 @@ mod diagnostics;
 /// Default type visitor (`TypeVisitor`) does most of the job, but it has some shortcomings.
 /// First, it doesn't have overridable `fn visit_trait_ref`, so we have to catch trait def-ids
 /// manually. Second, it doesn't visit some type components like signatures of fn types, or traits
-/// in `impl Trait`, see individual commits in `DefIdVisitorSkeleton::visit_ty`.
+/// in `impl Trait`, see individual comments in `DefIdVisitorSkeleton::visit_ty`.
 trait DefIdVisitor<'a, 'tcx: 'a> {
     fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>;
     fn shallow(&self) -> bool { false }
@@ -1579,10 +1579,15 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx>
             // No subitems.
             hir::ItemKind::GlobalAsm(..) => {}
             // Subitems of these items have inherited publicity.
-            hir::ItemKind::Const(..) | hir::ItemKind::Static(..) | hir::ItemKind::Fn(..) |
-            hir::ItemKind::Existential(..) | hir::ItemKind::Ty(..) => {
+            hir::ItemKind::Const(..) | hir::ItemKind::Static(..) |
+            hir::ItemKind::Fn(..) | hir::ItemKind::Ty(..) => {
                 self.check(item.id, item_visibility).generics().predicates().ty();
             }
+            hir::ItemKind::Existential(..) => {
+                // `ty()` for existential types is the underlying type,
+                // it's not a part of interface, so we skip it.
+                self.check(item.id, item_visibility).generics().predicates();
+            }
             hir::ItemKind::Trait(.., ref trait_item_refs) => {
                 self.check(item.id, item_visibility).generics().predicates();
 
diff --git a/src/test/ui/privacy/private-in-public-existential.rs b/src/test/ui/privacy/private-in-public-existential.rs
new file mode 100644
index 00000000000..95658f45df6
--- /dev/null
+++ b/src/test/ui/privacy/private-in-public-existential.rs
@@ -0,0 +1,15 @@
+// compile-pass
+
+#![feature(existential_type)]
+#![deny(private_in_public)]
+
+pub existential type Pub: Default;
+
+#[derive(Default)]
+struct Priv;
+
+fn check() -> Pub {
+    Priv
+}
+
+fn main() {}