Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a317fd9

Browse files
committedJun 12, 2024
Auto merge of #126076 - jswrenn:fix-45713, r=<try>
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 <!-- If this PR is related to an unstable feature or an otherwise tracked effort, please link to the relevant tracking issue here. If you don't know of a related tracking issue or there are none, feel free to ignore this. This PR will get automatically assigned to a reviewer. In case you would like a specific user to review your work, you can assign it to them by using r​? <reviewer name> -->
2 parents 1d43fbb + c2af856 commit a317fd9

File tree

9 files changed

+39
-48
lines changed

9 files changed

+39
-48
lines changed
 

‎Cargo.lock

+2
Original file line numberDiff line numberDiff line change
@@ -4594,10 +4594,12 @@ dependencies = [
45944594
"rustc_errors",
45954595
"rustc_fluent_macro",
45964596
"rustc_hir",
4597+
"rustc_infer",
45974598
"rustc_macros",
45984599
"rustc_middle",
45994600
"rustc_session",
46004601
"rustc_span",
4602+
"rustc_trait_selection",
46014603
"rustc_ty_utils",
46024604
"tracing",
46034605
]

‎compiler/rustc_privacy/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ rustc_data_structures = { path = "../rustc_data_structures" }
1111
rustc_errors = { path = "../rustc_errors" }
1212
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
1313
rustc_hir = { path = "../rustc_hir" }
14+
rustc_infer = { path = "../rustc_infer" }
1415
rustc_macros = { path = "../rustc_macros" }
1516
rustc_middle = { path = "../rustc_middle" }
1617
rustc_session = { path = "../rustc_session" }
1718
rustc_span = { path = "../rustc_span" }
19+
rustc_trait_selection = { path = "../rustc_trait_selection" }
1820
rustc_ty_utils = { path = "../rustc_ty_utils" }
1921
tracing = "0.1"
2022
# tidy-alphabetical-end

‎compiler/rustc_privacy/src/lib.rs

+24-2
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind};
2323
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
2424
use rustc_middle::query::Providers;
2525
use rustc_middle::ty::print::PrintTraitRefExt as _;
26-
use rustc_middle::ty::GenericArgs;
2726
use rustc_middle::ty::{self, Const, GenericParamDefKind};
27+
use rustc_middle::ty::{GenericArgs, ParamEnv};
2828
use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
2929
use rustc_middle::{bug, span_bug};
3030
use rustc_session::lint;
3131
use rustc_span::hygiene::Transparency;
3232
use rustc_span::symbol::{kw, sym, Ident};
3333
use rustc_span::Span;
34+
use rustc_trait_selection::infer::TyCtxtInferExt;
35+
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
3436
use tracing::debug;
3537

3638
use std::fmt;
@@ -1302,7 +1304,13 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
13021304

13031305
fn ty(&mut self) -> &mut Self {
13041306
self.in_primary_interface = true;
1305-
self.visit(self.tcx.type_of(self.item_def_id).instantiate_identity());
1307+
let ty = self.tcx.type_of(self.item_def_id).instantiate_identity();
1308+
1309+
// Attempt to normalize `ty`
1310+
let param_env = self.tcx.param_env(self.item_def_id);
1311+
let maybe_normalized_ty = try_normalize(self.tcx, param_env, ty);
1312+
1313+
self.visit(maybe_normalized_ty.unwrap_or(ty));
13061314
self
13071315
}
13081316

@@ -1763,3 +1771,17 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
17631771
checker.check_item(id);
17641772
}
17651773
}
1774+
1775+
/// Attempts to deeply normalize `ty`.
1776+
fn try_normalize<'tcx>(
1777+
tcx: TyCtxt<'tcx>,
1778+
param_env: ParamEnv<'tcx>,
1779+
ty: Ty<'tcx>,
1780+
) -> Result<Ty<'tcx>, ()> {
1781+
let infcx = tcx.infer_ctxt().with_next_trait_solver(true).build();
1782+
let ocx = ObligationCtxt::new(&infcx);
1783+
let cause = ObligationCause::dummy();
1784+
let Ok(ty) = ocx.deeply_normalize(&cause, param_env, ty) else { return Err(()) };
1785+
let errors = ocx.select_all_or_error();
1786+
if errors.is_empty() { Ok(ty) } else { Err(()) }
1787+
}

‎src/tools/tidy/src/issues.txt

-1
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,6 @@ ui/const-generics/issues/issue-80062.rs
623623
ui/const-generics/issues/issue-80375.rs
624624
ui/const-generics/issues/issue-82956.rs
625625
ui/const-generics/issues/issue-83249.rs
626-
ui/const-generics/issues/issue-83288.rs
627626
ui/const-generics/issues/issue-83466.rs
628627
ui/const-generics/issues/issue-83765.rs
629628
ui/const-generics/issues/issue-84659.rs

‎tests/ui/const-generics/issues/issue-83288.rs ‎tests/crashes/83288.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@ build-pass
1+
//@ known-bug: rust-lang/rust#83288
22

33
#![allow(incomplete_features)]
44
#![feature(generic_const_exprs)]

‎tests/ui/associated-inherent-types/private-in-public.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
#![crate_type = "lib"]
66

77
pub type PubAlias0 = PubTy::PrivAssocTy;
8-
//~^ WARNING associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
8+
99
pub type PubAlias1 = PrivTy::PubAssocTy;
10-
//~^ WARNING type `PrivTy` is more private than the item `PubAlias1`
10+
1111
pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
1212
//~^ WARNING type `PrivTy` is more private than the item `PubAlias2`
1313

Original file line numberDiff line numberDiff line change
@@ -1,28 +1,3 @@
1-
warning: associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
2-
--> $DIR/private-in-public.rs:7:1
3-
|
4-
LL | pub type PubAlias0 = PubTy::PrivAssocTy;
5-
| ^^^^^^^^^^^^^^^^^^ type alias `PubAlias0` is reachable at visibility `pub`
6-
|
7-
note: but associated type `PubTy::PrivAssocTy` is only usable at visibility `pub(crate)`
8-
--> $DIR/private-in-public.rs:16:5
9-
|
10-
LL | type PrivAssocTy = ();
11-
| ^^^^^^^^^^^^^^^^
12-
= note: `#[warn(private_interfaces)]` on by default
13-
14-
warning: type `PrivTy` is more private than the item `PubAlias1`
15-
--> $DIR/private-in-public.rs:9:1
16-
|
17-
LL | pub type PubAlias1 = PrivTy::PubAssocTy;
18-
| ^^^^^^^^^^^^^^^^^^ type alias `PubAlias1` is reachable at visibility `pub`
19-
|
20-
note: but type `PrivTy` is only usable at visibility `pub(crate)`
21-
--> $DIR/private-in-public.rs:20:1
22-
|
23-
LL | struct PrivTy;
24-
| ^^^^^^^^^^^^^
25-
261
warning: type `PrivTy` is more private than the item `PubAlias2`
272
--> $DIR/private-in-public.rs:11:1
283
|
@@ -34,6 +9,7 @@ note: but type `PrivTy` is only usable at visibility `pub(crate)`
349
|
3510
LL | struct PrivTy;
3611
| ^^^^^^^^^^^^^
12+
= note: `#[warn(private_interfaces)]` on by default
3713

38-
warning: 3 warnings emitted
14+
warning: 1 warning emitted
3915

‎tests/ui/privacy/projections2.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ mod m {
1717

1818
impl Trait4 for u8 {
1919
type A<T: Trait> = <u8 as Trait3>::A<T>;
20-
//~^ ERROR: private associated type `Trait3::A` in public interface
21-
//~| ERROR: private trait `Trait3` in public interface
20+
//~^ ERROR: private type `Priv` in public interface
2221
}
2322
}
2423

‎tests/ui/privacy/projections2.stderr

+5-14
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,15 @@ LL | struct Priv;
1111
| ^^^^^^^^^^^
1212
= note: `#[warn(private_interfaces)]` on by default
1313

14-
error[E0446]: private associated type `Trait3::A` in public interface
14+
error[E0446]: private type `Priv` in public interface
1515
--> $DIR/projections2.rs:19:9
1616
|
17-
LL | type A<T: Trait>;
18-
| ---------------- `Trait3::A` declared as private
19-
...
20-
LL | type A<T: Trait> = <u8 as Trait3>::A<T>;
21-
| ^^^^^^^^^^^^^^^^ can't leak private associated type
22-
23-
error[E0446]: private trait `Trait3` in public interface
24-
--> $DIR/projections2.rs:19:9
25-
|
26-
LL | trait Trait3 {
27-
| ------------ `Trait3` declared as private
17+
LL | struct Priv;
18+
| ----------- `Priv` declared as private
2819
...
2920
LL | type A<T: Trait> = <u8 as Trait3>::A<T>;
30-
| ^^^^^^^^^^^^^^^^ can't leak private trait
21+
| ^^^^^^^^^^^^^^^^ can't leak private type
3122

32-
error: aborting due to 2 previous errors; 1 warning emitted
23+
error: aborting due to 1 previous error; 1 warning emitted
3324

3425
For more information about this error, try `rustc --explain E0446`.

0 commit comments

Comments
 (0)
Failed to load comments.