diff --git a/Cargo.lock b/Cargo.lock index e5ea9fee8a6d8..21ff5aa83f5f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4594,10 +4594,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", ] diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml index f998e0ff1547f..fb615b1a5afb1 100644 --- a/compiler/rustc_privacy/Cargo.toml +++ b/compiler/rustc_privacy/Cargo.toml @@ -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 diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index fb57d42f6df18..270f4b3d26015 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -23,14 +23,16 @@ use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind}; use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; use rustc_middle::query::Providers; use rustc_middle::ty::print::PrintTraitRefExt as _; -use rustc_middle::ty::GenericArgs; use rustc_middle::ty::{self, Const, GenericParamDefKind}; +use rustc_middle::ty::{GenericArgs, ParamEnv}; use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_middle::{bug, span_bug}; 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 std::fmt; @@ -1302,7 +1304,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 } @@ -1763,3 +1771,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: ParamEnv<'tcx>, + ty: Ty<'tcx>, +) -> Result, ()> { + 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(()) } +} diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt index a6ba8959f0c5d..0dbd47e918ed1 100644 --- a/src/tools/tidy/src/issues.txt +++ b/src/tools/tidy/src/issues.txt @@ -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 diff --git a/tests/ui/const-generics/issues/issue-83288.rs b/tests/crashes/83288.rs similarity index 97% rename from tests/ui/const-generics/issues/issue-83288.rs rename to tests/crashes/83288.rs index 4260170d1ac3f..b2ae0f1cda03a 100644 --- a/tests/ui/const-generics/issues/issue-83288.rs +++ b/tests/crashes/83288.rs @@ -1,4 +1,4 @@ -//@ build-pass +//@ known-bug: rust-lang/rust#83288 #![allow(incomplete_features)] #![feature(generic_const_exprs)] diff --git a/tests/ui/associated-inherent-types/private-in-public.rs b/tests/ui/associated-inherent-types/private-in-public.rs index a950d1735c6d7..35e4acb30cef2 100644 --- a/tests/ui/associated-inherent-types/private-in-public.rs +++ b/tests/ui/associated-inherent-types/private-in-public.rs @@ -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; //~^ WARNING type `PrivTy` is more private than the item `PubAlias2` diff --git a/tests/ui/associated-inherent-types/private-in-public.stderr b/tests/ui/associated-inherent-types/private-in-public.stderr index 076bbd78ae910..55b9d5c45bf65 100644 --- a/tests/ui/associated-inherent-types/private-in-public.stderr +++ b/tests/ui/associated-inherent-types/private-in-public.stderr @@ -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 diff --git a/tests/ui/privacy/projections2.rs b/tests/ui/privacy/projections2.rs index 1afbf6d196e58..b389526fcc0f7 100644 --- a/tests/ui/privacy/projections2.rs +++ b/tests/ui/privacy/projections2.rs @@ -17,8 +17,7 @@ mod m { impl Trait4 for u8 { type A = ::A; - //~^ ERROR: private associated type `Trait3::A` in public interface - //~| ERROR: private trait `Trait3` in public interface + //~^ ERROR: private type `Priv` in public interface } } diff --git a/tests/ui/privacy/projections2.stderr b/tests/ui/privacy/projections2.stderr index 6eae9643c5a8e..9723feaa37981 100644 --- a/tests/ui/privacy/projections2.stderr +++ b/tests/ui/privacy/projections2.stderr @@ -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; - | ---------------- `Trait3::A` declared as private -... -LL | type A = ::A; - | ^^^^^^^^^^^^^^^^ 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 = ::A; - | ^^^^^^^^^^^^^^^^ 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`.