about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDavid Wood <david.wood@huawei.com>2023-12-07 17:06:08 +0000
committerDavid Wood <david.wood@huawei.com>2023-12-08 14:26:03 +0000
commit5d977240023003f9f8d82e42fd7d45bbfd630954 (patch)
treebd40473434742260626ffa7630915d8b7704b9b0
parent5ea62560f294947e55b0cf895dae23fe3c41777c (diff)
downloadrust-5d977240023003f9f8d82e42fd7d45bbfd630954.tar.gz
rust-5d977240023003f9f8d82e42fd7d45bbfd630954.zip
privacy: visit trait def id of projections
A refactoring in #117076 changed the `DefIdVisitorSkeleton` to avoid
calling `visit_projection_ty` for `ty::Projection` aliases, and instead
just iterate over the args - this makes sense, as `visit_projection_ty`
will indirectly visit all of the same args, but in doing so, will also
create a `TraitRef` containing the trait's `DefId`, which also gets
visited. The trait's `DefId` isn't visited when we only visit the
arguments without separating them into `TraitRef` and own args first.

Signed-off-by: David Wood <david@davidtw.co>
-rw-r--r--compiler/rustc_privacy/src/lib.rs13
-rw-r--r--tests/ui/privacy/auxiliary/issue-117997.rs35
-rw-r--r--tests/ui/privacy/issue-117997.rs8
-rw-r--r--tests/ui/privacy/private-in-public.rs2
-rw-r--r--tests/ui/privacy/private-in-public.stderr50
5 files changed, 89 insertions, 19 deletions
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 9064cb6e875..e49282e638a 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -218,20 +218,21 @@ where
                     return ControlFlow::Continue(());
                 }
 
-                let kind = match kind {
-                    ty::Inherent | ty::Projection => "associated type",
-                    ty::Weak => "type alias",
-                    ty::Opaque => unreachable!(),
-                };
                 self.def_id_visitor.visit_def_id(
                     data.def_id,
-                    kind,
+                    match kind {
+                        ty::Inherent | ty::Projection => "associated type",
+                        ty::Weak => "type alias",
+                        ty::Opaque => unreachable!(),
+                    },
                     &LazyDefPathStr { def_id: data.def_id, tcx },
                 )?;
 
                 // This will also visit args if necessary, so we don't need to recurse.
                 return if V::SHALLOW {
                     ControlFlow::Continue(())
+                } else if kind == ty::Projection {
+                    self.visit_projection_ty(data)
                 } else {
                     data.args.iter().try_for_each(|subst| subst.visit_with(self))
                 };
diff --git a/tests/ui/privacy/auxiliary/issue-117997.rs b/tests/ui/privacy/auxiliary/issue-117997.rs
new file mode 100644
index 00000000000..6f71cc2ba35
--- /dev/null
+++ b/tests/ui/privacy/auxiliary/issue-117997.rs
@@ -0,0 +1,35 @@
+// no-prefer-dynamic
+// compile-flags: --crate-type=rlib
+
+pub use impl_mod::TraitImplementer as Implementer;
+
+pub use trait_mod::get_assoc;
+
+mod impl_mod {
+    use crate::trait_mod::TraitWithAssocType;
+
+    pub struct TraitImplementer {}
+    pub struct AssociatedType {}
+
+    impl AssociatedType {
+        pub fn method_on_assoc(&self) -> i32 {
+            todo!()
+        }
+    }
+
+    impl TraitWithAssocType for TraitImplementer {
+        type AssocType = AssociatedType;
+    }
+}
+
+mod trait_mod {
+    use crate::Implementer;
+
+    pub fn get_assoc() -> <Implementer as TraitWithAssocType>::AssocType {
+        todo!()
+    }
+
+    pub trait TraitWithAssocType {
+        type AssocType;
+    }
+}
diff --git a/tests/ui/privacy/issue-117997.rs b/tests/ui/privacy/issue-117997.rs
new file mode 100644
index 00000000000..d8284ef2997
--- /dev/null
+++ b/tests/ui/privacy/issue-117997.rs
@@ -0,0 +1,8 @@
+// aux-build:issue-117997.rs
+// build-pass
+
+extern crate issue_117997;
+
+pub fn main() {
+    issue_117997::get_assoc().method_on_assoc();
+}
diff --git a/tests/ui/privacy/private-in-public.rs b/tests/ui/privacy/private-in-public.rs
index 3fff2d51710..7b8e0fbe6b6 100644
--- a/tests/ui/privacy/private-in-public.rs
+++ b/tests/ui/privacy/private-in-public.rs
@@ -106,6 +106,7 @@ mod aliases_pub {
     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
     //~^ WARNING type `aliases_pub::Priv` is more private than the item `aliases_pub::f3`
     //~| WARNING associated type `aliases_pub::PrivTr::Assoc` is more private than the item `aliases_pub::f3`
+    //~^^^ WARNING trait `aliases_pub::PrivTr` is more private than the item `aliases_pub::f3`
 
     impl PrivUseAlias {
         pub fn f(arg: Priv) {}
@@ -135,6 +136,7 @@ mod aliases_priv {
     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
     //~^ WARNING type `aliases_priv::Priv` is more private than the item `aliases_priv::f3`
     //~| WARNING associated type `aliases_priv::PrivTr::Assoc` is more private than the item `aliases_priv::f3`
+    //~^^^ WARNING trait `aliases_priv::PrivTr` is more private than the item `aliases_priv::f3`
 }
 
 mod aliases_params {
diff --git a/tests/ui/privacy/private-in-public.stderr b/tests/ui/privacy/private-in-public.stderr
index 49cc2e19bf0..ff3061337ff 100644
--- a/tests/ui/privacy/private-in-public.stderr
+++ b/tests/ui/privacy/private-in-public.stderr
@@ -288,6 +288,18 @@ note: but associated type `aliases_pub::PrivTr::Assoc` is only usable at visibil
 LL |         type Assoc = m::Pub3;
    |         ^^^^^^^^^^
 
+warning: trait `aliases_pub::PrivTr` is more private than the item `aliases_pub::f3`
+  --> $DIR/private-in-public.rs:106:5
+   |
+LL |     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_pub::f3` is reachable at visibility `pub(crate)`
+   |
+note: but trait `aliases_pub::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:100:5
+   |
+LL |     trait PrivTr {
+   |     ^^^^^^^^^^^^
+
 warning: type `aliases_pub::Priv` is more private than the item `aliases_pub::f3`
   --> $DIR/private-in-public.rs:106:5
    |
@@ -301,76 +313,88 @@ LL |     struct Priv;
    |     ^^^^^^^^^^^
 
 warning: type `Priv1` is more private than the item `aliases_priv::f1`
-  --> $DIR/private-in-public.rs:133:5
+  --> $DIR/private-in-public.rs:134:5
    |
 LL |     pub fn f1(arg: PrivUseAlias) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f1` is reachable at visibility `pub(crate)`
    |
 note: but type `Priv1` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public.rs:118:5
+  --> $DIR/private-in-public.rs:119:5
    |
 LL |     struct Priv1;
    |     ^^^^^^^^^^^^
 
 warning: type `Priv2` is more private than the item `aliases_priv::f2`
-  --> $DIR/private-in-public.rs:134:5
+  --> $DIR/private-in-public.rs:135:5
    |
 LL |     pub fn f2(arg: PrivAlias) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f2` is reachable at visibility `pub(crate)`
    |
 note: but type `Priv2` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public.rs:119:5
+  --> $DIR/private-in-public.rs:120:5
    |
 LL |     struct Priv2;
    |     ^^^^^^^^^^^^
 
 warning: associated type `aliases_priv::PrivTr::Assoc` is more private than the item `aliases_priv::f3`
-  --> $DIR/private-in-public.rs:135:5
+  --> $DIR/private-in-public.rs:136:5
    |
 LL |     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f3` is reachable at visibility `pub(crate)`
    |
 note: but associated type `aliases_priv::PrivTr::Assoc` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public.rs:129:9
+  --> $DIR/private-in-public.rs:130:9
    |
 LL |         type Assoc = Priv3;
    |         ^^^^^^^^^^
 
+warning: trait `aliases_priv::PrivTr` is more private than the item `aliases_priv::f3`
+  --> $DIR/private-in-public.rs:136:5
+   |
+LL |     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f3` is reachable at visibility `pub(crate)`
+   |
+note: but trait `aliases_priv::PrivTr` is only usable at visibility `pub(self)`
+  --> $DIR/private-in-public.rs:129:5
+   |
+LL |     trait PrivTr {
+   |     ^^^^^^^^^^^^
+
 warning: type `aliases_priv::Priv` is more private than the item `aliases_priv::f3`
-  --> $DIR/private-in-public.rs:135:5
+  --> $DIR/private-in-public.rs:136:5
    |
 LL |     pub fn f3(arg: <Priv as PrivTr>::Assoc) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_priv::f3` is reachable at visibility `pub(crate)`
    |
 note: but type `aliases_priv::Priv` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public.rs:116:5
+  --> $DIR/private-in-public.rs:117:5
    |
 LL |     struct Priv;
    |     ^^^^^^^^^^^
 
 warning: type `aliases_params::Priv` is more private than the item `aliases_params::f2`
-  --> $DIR/private-in-public.rs:145:5
+  --> $DIR/private-in-public.rs:147:5
    |
 LL |     pub fn f2(arg: PrivAliasGeneric) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_params::f2` is reachable at visibility `pub(crate)`
    |
 note: but type `aliases_params::Priv` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public.rs:141:5
+  --> $DIR/private-in-public.rs:143:5
    |
 LL |     struct Priv;
    |     ^^^^^^^^^^^
 
 warning: type `aliases_params::Priv` is more private than the item `aliases_params::f3`
-  --> $DIR/private-in-public.rs:147:5
+  --> $DIR/private-in-public.rs:149:5
    |
 LL |     pub fn f3(arg: Result<u8>) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ function `aliases_params::f3` is reachable at visibility `pub(crate)`
    |
 note: but type `aliases_params::Priv` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public.rs:141:5
+  --> $DIR/private-in-public.rs:143:5
    |
 LL |     struct Priv;
    |     ^^^^^^^^^^^
 
-warning: 31 warnings emitted
+warning: 33 warnings emitted