From dbe6930286a202c024cfab1236437d64689181d7 Mon Sep 17 00:00:00 2001 From: Jack Wrenn Date: Tue, 4 Jun 2024 13:56:40 +0000 Subject: [PATCH] privacy: normalize associated types before visiting This permits associated types to reference private types and traits, so long as the normalized type does not itself violate type privacy. Fixes #45713 --- compiler/rustc_privacy/src/lib.rs | 12 +++++++++++- tests/ui/privacy/projections2.rs | 3 +-- tests/ui/privacy/projections2.stderr | 19 +++++-------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 2039e994aaae0..004de9f01725d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1298,7 +1298,17 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { fn ty(&mut self) -> &mut Self { self.in_primary_interface = true; - self.visit(self.tcx.type_of(self.item_def_id).instantiate_identity()); + let ty = self.tcx.type_of(self.item_def_id).instantiate_identity(); + + // if `in_assoc_ty`, attempt to normalize `ty` + let maybe_normalized_ty = if self.in_assoc_ty { + let param_env = self.tcx.param_env(self.item_def_id); + self.tcx.try_normalize_erasing_regions(param_env, ty).ok() + } else { + None + }; + + self.visit(maybe_normalized_ty.unwrap_or(ty)); self } diff --git a/tests/ui/privacy/projections2.rs b/tests/ui/privacy/projections2.rs index 1afbf6d196e58..b389526fcc0f7 100644 --- a/tests/ui/privacy/projections2.rs +++ b/tests/ui/privacy/projections2.rs @@ -17,8 +17,7 @@ mod m { impl Trait4 for u8 { type A = ::A; - //~^ ERROR: private associated type `Trait3::A` in public interface - //~| ERROR: private trait `Trait3` in public interface + //~^ ERROR: private type `Priv` in public interface } } diff --git a/tests/ui/privacy/projections2.stderr b/tests/ui/privacy/projections2.stderr index 6eae9643c5a8e..9723feaa37981 100644 --- a/tests/ui/privacy/projections2.stderr +++ b/tests/ui/privacy/projections2.stderr @@ -11,24 +11,15 @@ LL | struct Priv; | ^^^^^^^^^^^ = note: `#[warn(private_interfaces)]` on by default -error[E0446]: private associated type `Trait3::A` in public interface +error[E0446]: private type `Priv` in public interface --> $DIR/projections2.rs:19:9 | -LL | type A; - | ---------------- `Trait3::A` declared as private -... -LL | type A = ::A; - | ^^^^^^^^^^^^^^^^ can't leak private associated type - -error[E0446]: private trait `Trait3` in public interface - --> $DIR/projections2.rs:19:9 - | -LL | trait Trait3 { - | ------------ `Trait3` declared as private +LL | struct Priv; + | ----------- `Priv` declared as private ... LL | type A = ::A; - | ^^^^^^^^^^^^^^^^ can't leak private trait + | ^^^^^^^^^^^^^^^^ can't leak private type -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error; 1 warning emitted For more information about this error, try `rustc --explain E0446`.