Skip to content

Commit

Permalink
privacy: visit trait def id of projections
Browse files Browse the repository at this point in the history
A refactoring in rust-lang#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 <[email protected]>
  • Loading branch information
davidtwco committed Dec 8, 2023
1 parent 5ea6256 commit 5d97724
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 19 deletions.
13 changes: 7 additions & 6 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
};
Expand Down
35 changes: 35 additions & 0 deletions tests/ui/privacy/auxiliary/issue-117997.rs
Original file line number Diff line number Diff line change
@@ -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;
}
}
8 changes: 8 additions & 0 deletions tests/ui/privacy/issue-117997.rs
Original file line number Diff line number Diff line change
@@ -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();
}
2 changes: 2 additions & 0 deletions tests/ui/privacy/private-in-public.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {}
Expand Down Expand Up @@ -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 {
Expand Down
50 changes: 37 additions & 13 deletions tests/ui/privacy/private-in-public.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand All @@ -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

0 comments on commit 5d97724

Please sign in to comment.