Skip to content
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

privacy: normalize associated types before visiting #126076

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
@@ -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",
]
2 changes: 2 additions & 0 deletions compiler/rustc_privacy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -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
@@ -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};

@@ -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
}

@@ -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
@@ -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
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)]
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
@@ -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`

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
|
@@ -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
@@ -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
}
}

19 changes: 5 additions & 14 deletions tests/ui/privacy/projections2.stderr
Original file line number Diff line number Diff line change
@@ -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