From 5d977240023003f9f8d82e42fd7d45bbfd630954 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 7 Dec 2023 17:06:08 +0000 Subject: [PATCH] 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 --- compiler/rustc_privacy/src/lib.rs | 13 +++--- tests/ui/privacy/auxiliary/issue-117997.rs | 35 +++++++++++++++ tests/ui/privacy/issue-117997.rs | 8 ++++ tests/ui/privacy/private-in-public.rs | 2 + tests/ui/privacy/private-in-public.stderr | 50 ++++++++++++++++------ 5 files changed, 89 insertions(+), 19 deletions(-) create mode 100644 tests/ui/privacy/auxiliary/issue-117997.rs create mode 100644 tests/ui/privacy/issue-117997.rs 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 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { 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() -> ::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 @@ impl PrivTr for Priv {} pub fn f3(arg: ::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 @@ pub fn f2(arg: PrivAlias) {} //~ WARNING type `Priv2` is more private than the i pub fn f3(arg: ::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: ::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: ::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: ::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: ::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) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 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