Skip to content

privacy: normalize associated types before visiting #126076

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4244,10 +4244,12 @@ dependencies = [
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_infer",
"rustc_macros",
"rustc_middle",
"rustc_session",
"rustc_span",
"rustc_trait_selection",
"rustc_ty_utils",
"tracing",
]
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_privacy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_infer = { path = "../rustc_infer" }
rustc_macros = { path = "../rustc_macros" }
rustc_middle = { path = "../rustc_middle" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_ty_utils = { path = "../rustc_ty_utils" }
tracing = "0.1"
# tidy-alphabetical-end
24 changes: 23 additions & 1 deletion compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ use rustc_session::lint;
use rustc_span::hygiene::Transparency;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::Span;
use rustc_trait_selection::infer::TyCtxtInferExt;
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
use tracing::debug;
use {rustc_attr as attr, rustc_hir as hir};

Expand Down Expand Up @@ -1307,7 +1309,13 @@ 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();

// Attempt to normalize `ty`
let param_env = self.tcx.param_env(self.item_def_id);
let maybe_normalized_ty = try_normalize(self.tcx, param_env, ty);

self.visit(maybe_normalized_ty.unwrap_or(ty));
self
}

Expand Down Expand Up @@ -1768,3 +1776,17 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
checker.check_item(id);
}
}

/// Attempts to deeply normalize `ty`.
fn try_normalize<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
ty: Ty<'tcx>,
) -> Result<Ty<'tcx>, ()> {
let infcx = tcx.infer_ctxt().with_next_trait_solver(true).build();
let ocx = ObligationCtxt::new(&infcx);
let cause = ObligationCause::dummy();
let Ok(ty) = ocx.deeply_normalize(&cause, param_env, ty) else { return Err(()) };
let errors = ocx.select_all_or_error();
if errors.is_empty() { Ok(ty) } else { Err(()) }
}
1 change: 0 additions & 1 deletion src/tools/tidy/src/issues.txt
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,6 @@ ui/const-generics/issues/issue-80062.rs
ui/const-generics/issues/issue-80375.rs
ui/const-generics/issues/issue-82956.rs
ui/const-generics/issues/issue-83249.rs
ui/const-generics/issues/issue-83288.rs
ui/const-generics/issues/issue-83466.rs
ui/const-generics/issues/issue-83765.rs
ui/const-generics/issues/issue-84659.rs
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//@ build-pass
//@ known-bug: rust-lang/rust#83288

#![allow(incomplete_features)]
#![feature(generic_const_exprs)]
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/associated-inherent-types/private-in-public.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#![crate_type = "lib"]

pub type PubAlias0 = PubTy::PrivAssocTy;
//~^ WARNING associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`

pub type PubAlias1 = PrivTy::PubAssocTy;
//~^ WARNING type `PrivTy` is more private than the item `PubAlias1`

pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
//~^ WARNING type `PrivTy` is more private than the item `PubAlias2`

Expand Down
28 changes: 2 additions & 26 deletions tests/ui/associated-inherent-types/private-in-public.stderr
Original file line number Diff line number Diff line change
@@ -1,28 +1,3 @@
warning: associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
--> $DIR/private-in-public.rs:7:1
|
LL | pub type PubAlias0 = PubTy::PrivAssocTy;
| ^^^^^^^^^^^^^^^^^^ type alias `PubAlias0` is reachable at visibility `pub`
|
note: but associated type `PubTy::PrivAssocTy` is only usable at visibility `pub(crate)`
--> $DIR/private-in-public.rs:16:5
|
LL | type PrivAssocTy = ();
| ^^^^^^^^^^^^^^^^
= note: `#[warn(private_interfaces)]` on by default

warning: type `PrivTy` is more private than the item `PubAlias1`
--> $DIR/private-in-public.rs:9:1
|
LL | pub type PubAlias1 = PrivTy::PubAssocTy;
| ^^^^^^^^^^^^^^^^^^ type alias `PubAlias1` is reachable at visibility `pub`
|
note: but type `PrivTy` is only usable at visibility `pub(crate)`
--> $DIR/private-in-public.rs:20:1
|
LL | struct PrivTy;
| ^^^^^^^^^^^^^

warning: type `PrivTy` is more private than the item `PubAlias2`
--> $DIR/private-in-public.rs:11:1
|
Expand All @@ -34,6 +9,7 @@ note: but type `PrivTy` is only usable at visibility `pub(crate)`
|
LL | struct PrivTy;
| ^^^^^^^^^^^^^
= note: `#[warn(private_interfaces)]` on by default

warning: 3 warnings emitted
warning: 1 warning emitted

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`.
Loading