Skip to content

Commit

Permalink
privacy: normalize associated types before visiting
Browse files Browse the repository at this point in the history
This permits associated types to reference private types and
traits, so long as the normalized type does not itself violate
type privacy.

Fixes rust-lang#45713
  • Loading branch information
jswrenn committed Sep 7, 2024
1 parent 4ff16a9 commit 5429bc8
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 17 deletions.
14 changes: 13 additions & 1 deletion compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1307,7 +1307,19 @@ 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`.
// Ideally, we would normalize in all circumstances, but doing so
// currently causes some unexpected type errors.
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
}

Expand Down
3 changes: 1 addition & 2 deletions tests/ui/privacy/projections2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ mod m {

impl Trait4 for u8 {
type A<T: Trait> = <u8 as Trait3>::A<T>;
//~^ ERROR: private associated type `Trait3::A` in public interface
//~| ERROR: private trait `Trait3` in public interface
//~^ ERROR: private type `Priv` in public interface
}
}

Expand Down
19 changes: 5 additions & 14 deletions tests/ui/privacy/projections2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Trait>;
| ---------------- `Trait3::A` declared as private
...
LL | type A<T: Trait> = <u8 as Trait3>::A<T>;
| ^^^^^^^^^^^^^^^^ 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<T: Trait> = <u8 as Trait3>::A<T>;
| ^^^^^^^^^^^^^^^^ 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`.

0 comments on commit 5429bc8

Please sign in to comment.