Repository: rust-lang/rust
Pull request: privacy: Fix type privacy holes in RPITITs

<!-- homu-ignore:start -->
*[View all comments](https://triagebot.infra.rust-lang.org/gh-comments/rust-lang/rust/pull/152543)*
<!-- homu-ignore:end -->

A subset of https://github.com/rust-lang/rust/pull/146470.

Private types in RPITITs now report hard errors.
Private types in bounds of associated types still only report the `private_bounds` lint due to unacceptable amount of breakage (https://github.com/rust-lang/rust/pull/146470#issuecomment-3682850214).

Closes https://github.com/rust-lang/rust/issues/144139

Changed files:
filename: compiler/rustc_privacy/src/lib.rs
patch: @@ -1595,13 +1595,14 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
         let mut check = self.check(item.def_id.expect_local(), vis, effective_vis);
 
         let is_assoc_ty = item.is_type();
-        check.hard_error = is_assoc_ty && !item.is_impl_trait_in_trait();
+        check.hard_error = is_assoc_ty;
         check.generics().predicates();
         if assoc_has_type_of(self.tcx, item) {
-            check.hard_error = check.hard_error && item.defaultness(self.tcx).has_value();
             check.ty();
         }
         if is_assoc_ty && item.container == AssocContainer::Trait {
+            // FIXME: too much breakage from reporting hard errors here, better wait for a fix
+            // from proper associated type normalization.
             check.hard_error = false;
             check.bounds();
         }

filename: tests/ui/privacy/private-in-public-warn.rs
patch: @@ -49,10 +49,10 @@ mod traits {
         fn f<T: PrivTr>(arg: T) {}
         //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::f`
         fn g() -> impl PrivTr;
-        //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}`
+        //~^ ERROR private trait `traits::PrivTr` in public interface
         //~| ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}`
         fn h() -> impl PrivTr {}
-        //~^ ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}`
+        //~^ ERROR private trait `traits::PrivTr` in public interface
         //~| ERROR trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}`
     }
     impl<T: PrivTr> Pub<T> {} //~ ERROR trait `traits::PrivTr` is more private than the item `traits::Pub<T>`
@@ -93,13 +93,13 @@ mod generics {
 
     pub trait Tr5 {
         fn required() -> impl PrivTr<Priv<()>>;
-        //~^ ERROR trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::required::{anon_assoc#0}`
-        //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}`
+        //~^ ERROR private trait `generics::PrivTr<generics::Priv<()>>` in public interface
+        //~| ERROR private type `generics::Priv<()>` in public interface
         //~| ERROR trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::required::{anon_assoc#0}`
         //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}`
         fn provided() -> impl PrivTr<Priv<()>> {}
-        //~^ ERROR trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::provided::{anon_assoc#0}`
-        //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}`
+        //~^ ERROR private trait `generics::PrivTr<generics::Priv<()>>` in public interface
+        //~| ERROR private type `generics::Priv<()>` in public interface
         //~| ERROR trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::provided::{anon_assoc#0}`
         //~| ERROR type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}`
     }

filename: tests/ui/privacy/private-in-public-warn.stderr
patch: @@ -194,17 +194,14 @@ note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
 LL |     trait PrivTr {}
    |     ^^^^^^^^^^^^
 
-error: trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}`
+error[E0446]: private trait `traits::PrivTr` in public interface
   --> $DIR/private-in-public-warn.rs:51:19
    |
-LL |         fn g() -> impl PrivTr;
-   |                   ^^^^^^^^^^^ opaque type `traits::Tr3::g::{anon_assoc#0}` is reachable at visibility `pub(crate)`
-   |
-note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public-warn.rs:37:5
-   |
 LL |     trait PrivTr {}
-   |     ^^^^^^^^^^^^
+   |     ------------ `traits::PrivTr` declared as private
+...
+LL |         fn g() -> impl PrivTr;
+   |                   ^^^^^^^^^^^ can't leak private trait
 
 error: trait `traits::PrivTr` is more private than the item `traits::Tr3::g::{anon_assoc#0}`
   --> $DIR/private-in-public-warn.rs:51:19
@@ -218,17 +215,14 @@ note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
 LL |     trait PrivTr {}
    |     ^^^^^^^^^^^^
 
-error: trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}`
+error[E0446]: private trait `traits::PrivTr` in public interface
   --> $DIR/private-in-public-warn.rs:54:19
    |
-LL |         fn h() -> impl PrivTr {}
-   |                   ^^^^^^^^^^^ opaque type `traits::Tr3::h::{anon_assoc#0}` is reachable at visibility `pub(crate)`
-   |
-note: but trait `traits::PrivTr` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public-warn.rs:37:5
-   |
 LL |     trait PrivTr {}
-   |     ^^^^^^^^^^^^
+   |     ------------ `traits::PrivTr` declared as private
+...
+LL |         fn h() -> impl PrivTr {}
+   |                   ^^^^^^^^^^^ can't leak private trait
 
 error: trait `traits::PrivTr` is more private than the item `traits::Tr3::h::{anon_assoc#0}`
   --> $DIR/private-in-public-warn.rs:54:19
@@ -350,29 +344,23 @@ note: but type `generics::Priv` is only usable at visibility `pub(self)`
 LL |     struct Priv<T = u8>(T);
    |     ^^^^^^^^^^^^^^^^^^^
 
-error: trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::required::{anon_assoc#0}`
+error[E0446]: private trait `generics::PrivTr<generics::Priv<()>>` in public interface
   --> $DIR/private-in-public-warn.rs:95:26
    |
-LL |         fn required() -> impl PrivTr<Priv<()>>;
-   |                          ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::required::{anon_assoc#0}` is reachable at visibility `pub(crate)`
-   |
-note: but trait `generics::PrivTr<generics::Priv<()>>` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public-warn.rs:84:5
-   |
 LL |     trait PrivTr<T> {}
-   |     ^^^^^^^^^^^^^^^
+   |     --------------- `generics::PrivTr<generics::Priv<()>>` declared as private
+...
+LL |         fn required() -> impl PrivTr<Priv<()>>;
+   |                          ^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
 
-error: type `generics::Priv<()>` is more private than the item `Tr5::required::{anon_assoc#0}`
+error[E0446]: private type `generics::Priv<()>` in public interface
   --> $DIR/private-in-public-warn.rs:95:26
    |
-LL |         fn required() -> impl PrivTr<Priv<()>>;
-   |                          ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::required::{anon_assoc#0}` is reachable at visibility `pub(crate)`
-   |
-note: but type `generics::Priv<()>` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public-warn.rs:82:5
-   |
 LL |     struct Priv<T = u8>(T);
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ------------------- `generics::Priv<()>` declared as private
+...
+LL |         fn required() -> impl PrivTr<Priv<()>>;
+   |                          ^^^^^^^^^^^^^^^^^^^^^ can't leak private type
 
 error: trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::required::{anon_assoc#0}`
   --> $DIR/private-in-public-warn.rs:95:26
@@ -398,29 +386,23 @@ note: but type `generics::Priv<()>` is only usable at visibility `pub(self)`
 LL |     struct Priv<T = u8>(T);
    |     ^^^^^^^^^^^^^^^^^^^
 
-error: trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::provided::{anon_assoc#0}`
+error[E0446]: private trait `generics::PrivTr<generics::Priv<()>>` in public interface
   --> $DIR/private-in-public-warn.rs:100:26
    |
-LL |         fn provided() -> impl PrivTr<Priv<()>> {}
-   |                          ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::provided::{anon_assoc#0}` is reachable at visibility `pub(crate)`
-   |
-note: but trait `generics::PrivTr<generics::Priv<()>>` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public-warn.rs:84:5
-   |
 LL |     trait PrivTr<T> {}
-   |     ^^^^^^^^^^^^^^^
+   |     --------------- `generics::PrivTr<generics::Priv<()>>` declared as private
+...
+LL |         fn provided() -> impl PrivTr<Priv<()>> {}
+   |                          ^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
 
-error: type `generics::Priv<()>` is more private than the item `Tr5::provided::{anon_assoc#0}`
+error[E0446]: private type `generics::Priv<()>` in public interface
   --> $DIR/private-in-public-warn.rs:100:26
    |
-LL |         fn provided() -> impl PrivTr<Priv<()>> {}
-   |                          ^^^^^^^^^^^^^^^^^^^^^ opaque type `Tr5::provided::{anon_assoc#0}` is reachable at visibility `pub(crate)`
-   |
-note: but type `generics::Priv<()>` is only usable at visibility `pub(self)`
-  --> $DIR/private-in-public-warn.rs:82:5
-   |
 LL |     struct Priv<T = u8>(T);
-   |     ^^^^^^^^^^^^^^^^^^^
+   |     ------------------- `generics::Priv<()>` declared as private
+...
+LL |         fn provided() -> impl PrivTr<Priv<()>> {}
+   |                          ^^^^^^^^^^^^^^^^^^^^^ can't leak private type
 
 error: trait `generics::PrivTr<generics::Priv<()>>` is more private than the item `Tr5::provided::{anon_assoc#0}`
   --> $DIR/private-in-public-warn.rs:100:26