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 50a1556

Browse files
committedJun 11, 2024
privacy: normalize types before visiting
Ref rust-lang#126076 (comment)
1 parent cc36e1e commit 50a1556

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
@@ -4479,10 +4479,12 @@ dependencies = [
44794479
"rustc_fluent_macro",
44804480
"rustc_hir",
44814481
"rustc_hir_analysis",
4482+
"rustc_infer",
44824483
"rustc_macros",
44834484
"rustc_middle",
44844485
"rustc_session",
44854486
"rustc_span",
4487+
"rustc_trait_selection",
44864488
"rustc_ty_utils",
44874489
"tracing",
44884490
]

‎compiler/rustc_privacy/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@ rustc_errors = { path = "../rustc_errors" }
1212
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
1313
rustc_hir = { path = "../rustc_hir" }
1414
rustc_hir_analysis = { path = "../rustc_hir_analysis" }
15+
rustc_infer = { path = "../rustc_infer" }
1516
rustc_macros = { path = "../rustc_macros" }
1617
rustc_middle = { path = "../rustc_middle" }
1718
rustc_session = { path = "../rustc_session" }
1819
rustc_span = { path = "../rustc_span" }
20+
rustc_trait_selection = { path = "../rustc_trait_selection" }
1921
rustc_ty_utils = { path = "../rustc_ty_utils" }
2022
tracing = "0.1"
2123
# 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::intravisit::{self, Visitor};
2323
use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind};
2424
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
2525
use rustc_middle::query::Providers;
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

3537
use std::fmt;
3638
use std::marker::PhantomData;
@@ -1300,15 +1302,9 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
13001302
self.in_primary_interface = true;
13011303
let ty = self.tcx.type_of(self.item_def_id).instantiate_identity();
13021304

1303-
// If `in_assoc_ty`, attempt to normalize `ty`.
1304-
// Ideally, we would normalize in all circumstances, but doing so
1305-
// currently causes some unexpected type errors.
1306-
let maybe_normalized_ty = if self.in_assoc_ty {
1307-
let param_env = self.tcx.param_env(self.item_def_id);
1308-
self.tcx.try_normalize_erasing_regions(param_env, ty).ok()
1309-
} else {
1310-
None
1311-
};
1305+
// Attempt to normalize `ty`
1306+
let param_env = self.tcx.param_env(self.item_def_id);
1307+
let maybe_normalized_ty = try_normalize(self.tcx, param_env, ty);
13121308

13131309
self.visit(maybe_normalized_ty.unwrap_or(ty));
13141310
self
@@ -1771,3 +1767,17 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
17711767
checker.check_item(id);
17721768
}
17731769
}
1770+
1771+
/// Attempts to deeply normalize `ty`.
1772+
fn try_normalize<'tcx>(
1773+
tcx: TyCtxt<'tcx>,
1774+
param_env: ParamEnv<'tcx>,
1775+
ty: Ty<'tcx>,
1776+
) -> Result<Ty<'tcx>, ()> {
1777+
let infcx = tcx.infer_ctxt().with_next_trait_solver(true).build();
1778+
let ocx = ObligationCtxt::new(&infcx);
1779+
let cause = ObligationCause::dummy();
1780+
let Ok(ty) = ocx.deeply_normalize(&cause, param_env, ty) else { return Err(()) };
1781+
let errors = ocx.select_all_or_error();
1782+
if errors.is_empty() { Ok(ty) } else { Err(()) }
1783+
}

‎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)
Failed to load comments.