Skip to content

Commit 4ff9e8f

Browse files
committed
privacy: normalize types before visiting
Ref #126076 (comment)
1 parent 44f7f7f commit 4ff9e8f

File tree

5 files changed

+28
-38
lines changed

5 files changed

+28
-38
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

+20-10
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;
@@ -1304,15 +1306,9 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
13041306
self.in_primary_interface = true;
13051307
let ty = self.tcx.type_of(self.item_def_id).instantiate_identity();
13061308

1307-
// If `in_assoc_ty`, attempt to normalize `ty`.
1308-
// Ideally, we would normalize in all circumstances, but doing so
1309-
// currently causes some unexpected type errors.
1310-
let maybe_normalized_ty = if self.in_assoc_ty {
1311-
let param_env = self.tcx.param_env(self.item_def_id);
1312-
self.tcx.try_normalize_erasing_regions(param_env, ty).ok()
1313-
} else {
1314-
None
1315-
};
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);
13161312

13171313
self.visit(maybe_normalized_ty.unwrap_or(ty));
13181314
self
@@ -1775,3 +1771,17 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
17751771
checker.check_item(id);
17761772
}
17771773
}
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+
}

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

0 commit comments

Comments
 (0)