diff options
| author | Bryanskiy <ivakin.kir@gmail.com> | 2023-06-19 17:06:00 +0300 |
|---|---|---|
| committer | Bryanskiy <ivakin.kir@gmail.com> | 2023-08-02 13:40:28 +0300 |
| commit | e26614e6a7f8003dfd2a756db070c6d04ca34c6f (patch) | |
| tree | 22bc39fc5f1b096999c0d39a245e9b6261efcdc8 /compiler | |
| parent | 5cbfee545543a8e3d91c54997c6bcd24d2054321 (diff) | |
| download | rust-e26614e6a7f8003dfd2a756db070c6d04ca34c6f.tar.gz rust-e26614e6a7f8003dfd2a756db070c6d04ca34c6f.zip | |
Replace old private-in-public diagnostic with type privacy lints
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0445.md | 8 | ||||
| -rw-r--r-- | compiler/rustc_error_codes/src/error_codes/E0446.md | 46 | ||||
| -rw-r--r-- | compiler/rustc_lint/src/lib.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_lint_defs/src/builtin.rs | 49 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/hir/map/mod.rs | 1 | ||||
| -rw-r--r-- | compiler/rustc_middle/src/ty/mod.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_privacy/messages.ftl | 5 | ||||
| -rw-r--r-- | compiler/rustc_privacy/src/errors.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_privacy/src/lib.rs | 421 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/build_reduced_graph.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 4 |
12 files changed, 52 insertions, 515 deletions
diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index d104ff0891d..755e5e26ac6 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -607,6 +607,7 @@ E0794: include_str!("./error_codes/E0794.md"), // E0420, // merged into 532 // E0421, // merged into 531 // E0427, // merged into 530 +// E0445, // merged into 446 and type privacy lints // E0456, // plugin `..` is not available for triple `..` // E0465, // removed: merged with E0464 // E0467, // removed diff --git a/compiler/rustc_error_codes/src/error_codes/E0445.md b/compiler/rustc_error_codes/src/error_codes/E0445.md index e6a28a9c2c4..d47393194c5 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0445.md +++ b/compiler/rustc_error_codes/src/error_codes/E0445.md @@ -1,10 +1,10 @@ -A private trait was used on a public type parameter bound. +#### Note: this error code is no longer emitted by the compiler. -Erroneous code examples: +A private trait was used on a public type parameter bound. -```compile_fail,E0445 -#![deny(private_in_public)] +Previously erroneous code examples: +``` trait Foo { fn dummy(&self) { } } diff --git a/compiler/rustc_error_codes/src/error_codes/E0446.md b/compiler/rustc_error_codes/src/error_codes/E0446.md index 6ec47c4962c..ebbd83c683c 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0446.md +++ b/compiler/rustc_error_codes/src/error_codes/E0446.md @@ -1,16 +1,16 @@ -A private type was used in a public type signature. +A private type or trait was used in a public associated type signature. Erroneous code example: ```compile_fail,E0446 -#![deny(private_in_public)] -struct Bar(u32); - -mod foo { - use crate::Bar; - pub fn bar() -> Bar { // error: private type in public interface - Bar(0) - } +struct Bar; + +pub trait PubTr { + type Alias; +} + +impl PubTr for u8 { + type Alias = Bar; // error private type in public interface } fn main() {} @@ -22,13 +22,14 @@ This is done by using pub(crate) or pub(in crate::my_mod::etc) Example: ``` -struct Bar(u32); +struct Bar; + +pub(crate) trait PubTr { // only public to crate root + type Alias; +} -mod foo { - use crate::Bar; - pub(crate) fn bar() -> Bar { // only public to crate root - Bar(0) - } +impl PubTr for u8 { + type Alias = Bar; } fn main() {} @@ -38,12 +39,15 @@ The other way to solve this error is to make the private type public. Example: ``` -pub struct Bar(u32); // we set the Bar type public -mod foo { - use crate::Bar; - pub fn bar() -> Bar { // ok! - Bar(0) - } + +pub struct Bar; // we set the Bar trait public + +pub trait PubTr { + type Alias; +} + +impl PubTr for u8 { + type Alias = Bar; } fn main() {} diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 53089294fe2..6f1cdff2fc2 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -516,6 +516,11 @@ fn register_builtins(store: &mut LintStore) { "converted into hard error, see issue #82523 \ <https://github.com/rust-lang/rust/issues/82523> for more information", ); + store.register_removed( + "private_in_public", + "replaced with another group of lints, see RFC \ + <https://rust-lang.github.io/rfcs/2145-type-privacy.html> for more information", + ); } fn register_internals(store: &mut LintStore) { diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index 7e3b6e9e218..4d0d071d03f 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -983,44 +983,6 @@ declare_lint! { } declare_lint! { - /// The `private_in_public` lint detects private items in public - /// interfaces not caught by the old implementation. - /// - /// ### Example - /// - /// ```rust - /// # #![allow(unused)] - /// struct SemiPriv; - /// - /// mod m1 { - /// struct Priv; - /// impl super::SemiPriv { - /// pub fn f(_: Priv) {} - /// } - /// } - /// # fn main() {} - /// ``` - /// - /// {{produces}} - /// - /// ### Explanation - /// - /// The visibility rules are intended to prevent exposing private items in - /// public interfaces. This is a [future-incompatible] lint to transition - /// this to a hard error in the future. See [issue #34537] for more - /// details. - /// - /// [issue #34537]: https://github.com/rust-lang/rust/issues/34537 - /// [future-incompatible]: ../index.md#future-incompatible-lints - pub PRIVATE_IN_PUBLIC, - Warn, - "detect private items in public interfaces not caught by the old implementation", - @future_incompatible = FutureIncompatibleInfo { - reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>", - }; -} - -declare_lint! { /// The `invalid_alignment` lint detects dereferences of misaligned pointers during /// constant evaluation. /// @@ -3374,7 +3336,6 @@ declare_lint_pass! { PATTERNS_IN_FNS_WITHOUT_BODY, POINTER_STRUCTURAL_MATCH, PRIVATE_BOUNDS, - PRIVATE_IN_PUBLIC, PRIVATE_INTERFACES, PROC_MACRO_BACK_COMPAT, PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, @@ -4293,9 +4254,7 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail - /// # #![feature(type_privacy_lints)] /// # #![allow(unused)] - /// # #![allow(private_in_public)] /// #![deny(private_interfaces)] /// struct SemiPriv; /// @@ -4316,9 +4275,8 @@ declare_lint! { /// Having something private in primary interface guarantees that /// the item will be unusable from outer modules due to type privacy. pub PRIVATE_INTERFACES, - Allow, + Warn, "private type in primary interface of an item", - @feature_gate = sym::type_privacy_lints; } declare_lint! { @@ -4329,8 +4287,6 @@ declare_lint! { /// ### Example /// /// ```rust,compile_fail - /// # #![feature(type_privacy_lints)] - /// # #![allow(private_in_public)] /// # #![allow(unused)] /// #![deny(private_bounds)] /// @@ -4348,9 +4304,8 @@ declare_lint! { /// Having private types or traits in item bounds makes it less clear what interface /// the item actually provides. pub PRIVATE_BOUNDS, - Allow, + Warn, "private type in secondary interface of an item", - @feature_gate = sym::type_privacy_lints; } declare_lint! { diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 0256e09e4b5..26a28fc6405 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -1222,7 +1222,6 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh { tcx.sess.local_stable_crate_id().hash_stable(&mut hcx, &mut stable_hasher); // Hash visibility information since it does not appear in HIR. resolutions.visibilities.hash_stable(&mut hcx, &mut stable_hasher); - resolutions.has_pub_restricted.hash_stable(&mut hcx, &mut stable_hasher); stable_hasher.finish() }); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2b4c834f766..0d63c1f801e 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -162,8 +162,6 @@ pub struct ResolverOutputs { #[derive(Debug)] pub struct ResolverGlobalCtxt { pub visibilities: FxHashMap<LocalDefId, Visibility>, - /// This field is used to decide whether we should make `PRIVATE_IN_PUBLIC` a hard error. - pub has_pub_restricted: bool, /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. pub expn_that_defined: FxHashMap<LocalDefId, ExpnId>, pub effective_visibilities: EffectiveVisibilities, diff --git a/compiler/rustc_privacy/messages.ftl b/compiler/rustc_privacy/messages.ftl index b91e0d18a80..7785f1a7f81 100644 --- a/compiler/rustc_privacy/messages.ftl +++ b/compiler/rustc_privacy/messages.ftl @@ -11,11 +11,6 @@ privacy_in_public_interface = {$vis_descr} {$kind} `{$descr}` in public interfac privacy_item_is_private = {$kind} `{$descr}` is private .label = private {$kind} -privacy_private_in_public_lint = - {$vis_descr} {$kind} `{$descr}` in public interface (error {$kind -> - [trait] E0445 - *[other] E0446 - }) privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}` .item_label = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}` diff --git a/compiler/rustc_privacy/src/errors.rs b/compiler/rustc_privacy/src/errors.rs index da18f0c8268..b1242f82f4f 100644 --- a/compiler/rustc_privacy/src/errors.rs +++ b/compiler/rustc_privacy/src/errors.rs @@ -47,21 +47,6 @@ pub struct UnnamedItemIsPrivate { pub kind: &'static str, } -// Duplicate of `InPublicInterface` but with a different error code, shares the same slug. -#[derive(Diagnostic)] -#[diag(privacy_in_public_interface, code = "E0445")] -pub struct InPublicInterfaceTraits<'a> { - #[primary_span] - #[label] - pub span: Span, - pub vis_descr: &'static str, - pub kind: &'a str, - pub descr: DiagnosticArgFromDisplay<'a>, - #[label(privacy_visibility_label)] - pub vis_span: Span, -} - -// Duplicate of `InPublicInterfaceTraits` but with a different error code, shares the same slug. #[derive(Diagnostic)] #[diag(privacy_in_public_interface, code = "E0446")] pub struct InPublicInterface<'a> { @@ -92,14 +77,6 @@ pub struct FromPrivateDependencyInPublicInterface<'a> { } #[derive(LintDiagnostic)] -#[diag(privacy_private_in_public_lint)] -pub struct PrivateInPublicLint<'a> { - pub vis_descr: &'static str, - pub kind: &'a str, - pub descr: DiagnosticArgFromDisplay<'a>, -} - -#[derive(LintDiagnostic)] #[diag(privacy_unnameable_types_lint)] pub struct UnnameableTypesLint<'a> { #[label] diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 5fa780a372b..c1db182a31d 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -22,7 +22,7 @@ use rustc_hir as hir; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{AssocItemKind, ForeignItemKind, HirIdSet, ItemId, Node, PatKind}; +use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, Node, PatKind}; use rustc_middle::bug; use rustc_middle::hir::nested_filter; use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; @@ -42,8 +42,8 @@ use std::{fmt, mem}; use errors::{ FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface, - InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, PrivateInterfacesOrBoundsLint, - ReportEffectiveVisibility, UnnameableTypesLint, UnnamedItemIsPrivate, + ItemIsPrivate, PrivateInterfacesOrBoundsLint, ReportEffectiveVisibility, UnnameableTypesLint, + UnnamedItemIsPrivate, }; fluent_messages! { "../messages.ftl" } @@ -364,6 +364,7 @@ trait VisibilityLike: Sized { find.min } } + impl VisibilityLike for ty::Visibility { const MAX: Self = ty::Visibility::Public; fn new_min<const SHALLOW: bool>( @@ -1374,345 +1375,6 @@ impl<'tcx> DefIdVisitor<'tcx> for TypePrivacyVisitor<'tcx> { } /////////////////////////////////////////////////////////////////////////////// -/// Obsolete visitors for checking for private items in public interfaces. -/// These visitors are supposed to be kept in frozen state and produce an -/// "old error node set". For backward compatibility the new visitor reports -/// warnings instead of hard errors when the erroneous node is not in this old set. -/////////////////////////////////////////////////////////////////////////////// - -struct ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - effective_visibilities: &'a EffectiveVisibilities, - in_variant: bool, - // Set of errors produced by this obsolete visitor. - old_error_set: HirIdSet, -} - -struct ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> { - inner: &'a ObsoleteVisiblePrivateTypesVisitor<'b, 'tcx>, - /// Whether the type refers to private types. - contains_private: bool, - /// Whether we've recurred at all (i.e., if we're pointing at the - /// first type on which `visit_ty` was called). - at_outer_type: bool, - /// Whether that first type is a public path. - outer_type_is_public_path: bool, -} - -impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { - fn path_is_private_type(&self, path: &hir::Path<'_>) -> bool { - let did = match path.res { - Res::PrimTy(..) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } | Res::Err => { - return false; - } - res => res.def_id(), - }; - - // A path can only be private if: - // it's in this crate... - if let Some(did) = did.as_local() { - // .. and it corresponds to a private type in the AST (this returns - // `None` for type parameters). - match self.tcx.hir().find(self.tcx.hir().local_def_id_to_hir_id(did)) { - Some(Node::Item(_)) => !self.tcx.visibility(did).is_public(), - Some(_) | None => false, - } - } else { - false - } - } - - fn trait_is_public(&self, trait_id: LocalDefId) -> bool { - // FIXME: this would preferably be using `exported_items`, but all - // traits are exported currently (see `EmbargoVisitor.exported_trait`). - self.effective_visibilities.is_directly_public(trait_id) - } - - fn check_generic_bound(&mut self, bound: &hir::GenericBound<'_>) { - if let hir::GenericBound::Trait(ref trait_ref, _) = *bound { - if self.path_is_private_type(trait_ref.trait_ref.path) { - self.old_error_set.insert(trait_ref.trait_ref.hir_ref_id); - } - } - } - - fn item_is_public(&self, def_id: LocalDefId) -> bool { - self.effective_visibilities.is_reachable(def_id) || self.tcx.visibility(def_id).is_public() - } -} - -impl<'a, 'b, 'tcx, 'v> Visitor<'v> for ObsoleteCheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> { - fn visit_generic_arg(&mut self, generic_arg: &'v hir::GenericArg<'v>) { - match generic_arg { - hir::GenericArg::Type(t) => self.visit_ty(t), - hir::GenericArg::Infer(inf) => self.visit_ty(&inf.to_ty()), - hir::GenericArg::Lifetime(_) | hir::GenericArg::Const(_) => {} - } - } - - fn visit_ty(&mut self, ty: &hir::Ty<'_>) { - if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind { - if self.inner.path_is_private_type(path) { - self.contains_private = true; - // Found what we're looking for, so let's stop working. - return; - } - } - if let hir::TyKind::Path(_) = ty.kind { - if self.at_outer_type { - self.outer_type_is_public_path = true; - } - } - self.at_outer_type = false; - intravisit::walk_ty(self, ty) - } - - // Don't want to recurse into `[, .. expr]`. - fn visit_expr(&mut self, _: &hir::Expr<'_>) {} -} - -impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { - type NestedFilter = nested_filter::All; - - /// We want to visit items in the context of their containing - /// module and so forth, so supply a crate for doing a deep walk. - fn nested_visit_map(&mut self) -> Self::Map { - self.tcx.hir() - } - - fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - match item.kind { - // Contents of a private mod can be re-exported, so we need - // to check internals. - hir::ItemKind::Mod(_) => {} - - // An `extern {}` doesn't introduce a new privacy - // namespace (the contents have their own privacies). - hir::ItemKind::ForeignMod { .. } => {} - - hir::ItemKind::Trait(.., bounds, _) => { - if !self.trait_is_public(item.owner_id.def_id) { - return; - } - - for bound in bounds.iter() { - self.check_generic_bound(bound) - } - } - - // Impls need some special handling to try to offer useful - // error messages without (too many) false positives - // (i.e., we could just return here to not check them at - // all, or some worse estimation of whether an impl is - // publicly visible). - hir::ItemKind::Impl(ref impl_) => { - // `impl [... for] Private` is never visible. - let self_contains_private; - // `impl [... for] Public<...>`, but not `impl [... for] - // Vec<Public>` or `(Public,)`, etc. - let self_is_public_path; - - // Check the properties of the `Self` type: - { - let mut visitor = ObsoleteCheckTypeForPrivatenessVisitor { - inner: self, - contains_private: false, - at_outer_type: true, - outer_type_is_public_path: false, - }; - visitor.visit_ty(impl_.self_ty); - self_contains_private = visitor.contains_private; - self_is_public_path = visitor.outer_type_is_public_path; - } - - // Miscellaneous info about the impl: - - // `true` iff this is `impl Private for ...`. - let not_private_trait = impl_.of_trait.as_ref().map_or( - true, // no trait counts as public trait - |tr| { - if let Some(def_id) = tr.path.res.def_id().as_local() { - self.trait_is_public(def_id) - } else { - true // external traits must be public - } - }, - ); - - // `true` iff this is a trait impl or at least one method is public. - // - // `impl Public { $( fn ...() {} )* }` is not visible. - // - // This is required over just using the methods' privacy - // directly because we might have `impl<T: Foo<Private>> ...`, - // and we shouldn't warn about the generics if all the methods - // are private (because `T` won't be visible externally). - let trait_or_some_public_method = impl_.of_trait.is_some() - || impl_.items.iter().any(|impl_item_ref| { - let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - match impl_item.kind { - hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) => self - .effective_visibilities - .is_reachable(impl_item_ref.id.owner_id.def_id), - hir::ImplItemKind::Type(_) => false, - } - }); - - if !self_contains_private && not_private_trait && trait_or_some_public_method { - intravisit::walk_generics(self, &impl_.generics); - - match impl_.of_trait { - None => { - for impl_item_ref in impl_.items { - // This is where we choose whether to walk down - // further into the impl to check its items. We - // should only walk into public items so that we - // don't erroneously report errors for private - // types in private items. - let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - match impl_item.kind { - hir::ImplItemKind::Const(..) | hir::ImplItemKind::Fn(..) - if self.item_is_public(impl_item.owner_id.def_id) => - { - intravisit::walk_impl_item(self, impl_item) - } - hir::ImplItemKind::Type(..) => { - intravisit::walk_impl_item(self, impl_item) - } - _ => {} - } - } - } - Some(ref tr) => { - // Any private types in a trait impl fall into three - // categories. - // 1. mentioned in the trait definition - // 2. mentioned in the type params/generics - // 3. mentioned in the associated types of the impl - // - // Those in 1. can only occur if the trait is in - // this crate and will have been warned about on the - // trait definition (there's no need to warn twice - // so we don't check the methods). - // - // Those in 2. are warned via walk_generics and this - // call here. - intravisit::walk_path(self, tr.path); - - // Those in 3. are warned with this call. - for impl_item_ref in impl_.items { - let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - if let hir::ImplItemKind::Type(ty) = impl_item.kind { - self.visit_ty(ty); - } - } - } - } - } else if impl_.of_trait.is_none() && self_is_public_path { - // `impl Public<Private> { ... }`. Any public static - // methods will be visible as `Public::foo`. - let mut found_pub_static = false; - for impl_item_ref in impl_.items { - if self - .effective_visibilities - .is_reachable(impl_item_ref.id.owner_id.def_id) - || self.tcx.visibility(impl_item_ref.id.owner_id).is_public() - { - let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); - match impl_item_ref.kind { - AssocItemKind::Const => { - found_pub_static = true; - intravisit::walk_impl_item(self, impl_item); - } - AssocItemKind::Fn { has_self: false } => { - found_pub_static = true; - intravisit::walk_impl_item(self, impl_item); - } - _ => {} - } - } - } - if found_pub_static { - intravisit::walk_generics(self, &impl_.generics) - } - } - return; - } - - // `type ... = ...;` can contain private types, because - // we're introducing a new name. - hir::ItemKind::TyAlias(..) => return, - - // Not at all public, so we don't care. - _ if !self.item_is_public(item.owner_id.def_id) => { - return; - } - - _ => {} - } - - // We've carefully constructed it so that if we're here, then - // any `visit_ty`'s will be called on things that are in - // public signatures, i.e., things that we're interested in for - // this visitor. - intravisit::walk_item(self, item); - } - - fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) { - for predicate in generics.predicates { - match predicate { - hir::WherePredicate::BoundPredicate(bound_pred) => { - for bound in bound_pred.bounds.iter() { - self.check_generic_bound(bound) - } - } - hir::WherePredicate::RegionPredicate(_) => {} - hir::WherePredicate::EqPredicate(eq_pred) => { - self.visit_ty(eq_pred.rhs_ty); - } - } - } - } - - fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { - if self.effective_visibilities.is_reachable(item.owner_id.def_id) { - intravisit::walk_foreign_item(self, item) - } - } - - fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) { - if let hir::TyKind::Path(hir::QPath::Resolved(_, path)) = t.kind { - if self.path_is_private_type(path) { - self.old_error_set.insert(t.hir_id); - } - } - intravisit::walk_ty(self, t) - } - - fn visit_variant(&mut self, v: &'tcx hir::Variant<'tcx>) { - if self.effective_visibilities.is_reachable(v.def_id) { - self.in_variant = true; - intravisit::walk_variant(self, v); - self.in_variant = false; - } - } - - fn visit_field_def(&mut self, s: &'tcx hir::FieldDef<'tcx>) { - let vis = self.tcx.visibility(s.def_id); - if vis.is_public() || self.in_variant { - intravisit::walk_field_def(self, s); - } - } - - // We don't need to introspect into these at all: an - // expression/block context can't possibly contain exported things. - // (Making them no-ops stops us from traversing the whole AST without - // having to be super careful about our `walk_...` calls above.) - fn visit_block(&mut self, _: &'tcx hir::Block<'tcx>) {} - fn visit_expr(&mut self, _: &'tcx hir::Expr<'tcx>) {} -} - -/////////////////////////////////////////////////////////////////////////////// /// SearchInterfaceForPrivateItemsVisitor traverses an item's interface and /// finds any private components in it. /// PrivateItemsInPublicInterfacesVisitor ensures there are no private types @@ -1725,7 +1387,6 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> { /// The visitor checks that each component type is at least this visible. required_visibility: ty::Visibility, required_effective_vis: Option<EffectiveVisibility>, - has_old_errors: bool, in_assoc_ty: bool, in_primary_interface: bool, } @@ -1796,7 +1457,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id); let span = self.tcx.def_span(self.item_def_id.to_def_id()); let vis_span = self.tcx.def_span(def_id); - if !vis.is_at_least(self.required_visibility, self.tcx) { + if self.in_assoc_ty && !vis.is_at_least(self.required_visibility, self.tcx) { let vis_descr = match vis { ty::Visibility::Public => "public", ty::Visibility::Restricted(vis_def_id) => { @@ -1810,35 +1471,14 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> { } }; - if self.has_old_errors - || self.in_assoc_ty - || self.tcx.resolutions(()).has_pub_restricted - { - if kind == "trait" { - self.tcx.sess.emit_err(InPublicInterfaceTraits { - span, - vis_descr, - kind, - descr: descr.into(), - vis_span, - }); - } else { - self.tcx.sess.emit_err(InPublicInterface { - span, - vis_descr, - kind, - descr: descr.into(), - vis_span, - }); - } - } else { - self.tcx.emit_spanned_lint( - lint::builtin::PRIVATE_IN_PUBLIC, - hir_id, - span, - PrivateInPublicLint { vis_descr, kind, descr: descr.into() }, - ); - } + self.tcx.sess.emit_err(InPublicInterface { + span, + vis_descr, + kind, + descr: descr.into(), + vis_span, + }); + return false; } let Some(effective_vis) = self.required_effective_vis else { @@ -1909,7 +1549,6 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> { struct PrivateItemsInPublicInterfacesChecker<'tcx, 'a> { tcx: TyCtxt<'tcx>, - old_error_set_ancestry: HirIdSet, effective_visibilities: &'a EffectiveVisibilities, } @@ -1925,9 +1564,6 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> { item_def_id: def_id, required_visibility, required_effective_vis, - has_old_errors: self - .old_error_set_ancestry - .contains(&self.tcx.hir().local_def_id_to_hir_id(def_id)), in_assoc_ty: false, in_primary_interface: true, } @@ -2282,35 +1918,8 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities { fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) { let effective_visibilities = tcx.effective_visibilities(()); - - let mut visitor = ObsoleteVisiblePrivateTypesVisitor { - tcx, - effective_visibilities, - in_variant: false, - old_error_set: Default::default(), - }; - tcx.hir().walk_toplevel_module(&mut visitor); - - let mut old_error_set_ancestry = HirIdSet::default(); - for mut id in visitor.old_error_set.iter().copied() { - loop { - if !old_error_set_ancestry.insert(id) { - break; - } - let parent = tcx.hir().parent_id(id); - if parent == id { - break; - } - id = parent; - } - } - - // Check for private types and traits in public interfaces. - let mut checker = PrivateItemsInPublicInterfacesChecker { - tcx, - old_error_set_ancestry, - effective_visibilities, - }; + // Check for private types in public interfaces. + let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities }; for id in tcx.hir().items() { checker.check_item(id); diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 2f432799022..83ab5d5e68d 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -247,8 +247,6 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> { }) } ast::VisibilityKind::Restricted { ref path, id, .. } => { - // Make `PRIVATE_IN_PUBLIC` lint a hard error. - self.r.has_pub_restricted = true; // For visibilities we are not ready to provide correct implementation of "uniform // paths" right now, so on 2018 edition we only allow module-relative paths for now. // On 2015 edition visibilities are resolved as crate-relative by default, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index da5e92a075a..d1dc8e3e71c 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -980,7 +980,6 @@ pub struct Resolver<'a, 'tcx> { glob_map: FxHashMap<LocalDefId, FxHashSet<Symbol>>, /// Visibilities in "lowered" form, for all entities that have them. visibilities: FxHashMap<LocalDefId, ty::Visibility>, - has_pub_restricted: bool, used_imports: FxHashSet<NodeId>, maybe_unused_trait_imports: FxIndexSet<LocalDefId>, @@ -1319,7 +1318,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { glob_map: Default::default(), visibilities, - has_pub_restricted: false, used_imports: FxHashSet::default(), maybe_unused_trait_imports: Default::default(), @@ -1435,7 +1433,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let proc_macros = self.proc_macros.iter().map(|id| self.local_def_id(*id)).collect(); let expn_that_defined = self.expn_that_defined; let visibilities = self.visibilities; - let has_pub_restricted = self.has_pub_restricted; let extern_crate_map = self.extern_crate_map; let maybe_unused_trait_imports = self.maybe_unused_trait_imports; let glob_map = self.glob_map; @@ -1453,7 +1450,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let global_ctxt = ResolverGlobalCtxt { expn_that_defined, visibilities, - has_pub_restricted, effective_visibilities, extern_crate_map, module_children: self.module_children, |
