Rollup merge of #112670 - petrochenkov:typriv, r=eholk

privacy: Type privacy lints fixes and cleanups

See individual commits.
Follow up to https://github.com/rust-lang/rust/pull/111801.
This commit is contained in:
Matthias Krüger 2023-06-29 05:48:39 +02:00 committed by GitHub
commit 42a495da7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 255 additions and 158 deletions

View File

@ -543,6 +543,8 @@ pub fn set(&self, features: &mut Features, span: Span) {
/// Allows creation of instances of a struct by moving fields that have /// Allows creation of instances of a struct by moving fields that have
/// not changed from prior instances of the same struct (RFC #2528) /// not changed from prior instances of the same struct (RFC #2528)
(active, type_changing_struct_update, "1.58.0", Some(86555), None), (active, type_changing_struct_update, "1.58.0", Some(86555), None),
/// Allows using type privacy lints (`private_interfaces`, `private_bounds`, `unnameable_types`).
(active, type_privacy_lints, "CURRENT_RUSTC_VERSION", Some(48054), None),
/// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE. /// Enables rustc to generate code that instructs libstd to NOT ignore SIGPIPE.
(active, unix_sigpipe, "1.65.0", Some(97889), None), (active, unix_sigpipe, "1.65.0", Some(97889), None),
/// Allows unsized fn parameters. /// Allows unsized fn parameters.

View File

@ -665,9 +665,7 @@ fn check_variant(&mut self, cx: &LateContext<'_>, v: &hir::Variant<'_>) {
impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations { impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id) if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
&& cx.tcx.local_visibility(item.owner_id.def_id).is_public())
{
return; return;
} }
let (def, ty) = match item.kind { let (def, ty) = match item.kind {
@ -786,9 +784,7 @@ pub struct MissingDebugImplementations {
impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations { impl<'tcx> LateLintPass<'tcx> for MissingDebugImplementations {
fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) { fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
if !(cx.effective_visibilities.is_reachable(item.owner_id.def_id) if !cx.effective_visibilities.is_reachable(item.owner_id.def_id) {
&& cx.tcx.local_visibility(item.owner_id.def_id).is_public())
{
return; return;
} }

View File

@ -4264,6 +4264,7 @@
/// ### Example /// ### Example
/// ///
/// ```rust,compile_fail /// ```rust,compile_fail
/// # #![feature(type_privacy_lints)]
/// # #![allow(unused)] /// # #![allow(unused)]
/// # #![allow(private_in_public)] /// # #![allow(private_in_public)]
/// #![deny(private_interfaces)] /// #![deny(private_interfaces)]
@ -4288,6 +4289,7 @@
pub PRIVATE_INTERFACES, pub PRIVATE_INTERFACES,
Allow, Allow,
"private type in primary interface of an item", "private type in primary interface of an item",
@feature_gate = sym::type_privacy_lints;
} }
declare_lint! { declare_lint! {
@ -4298,6 +4300,7 @@
/// ### Example /// ### Example
/// ///
/// ```rust,compile_fail /// ```rust,compile_fail
/// # #![feature(type_privacy_lints)]
/// # #![allow(private_in_public)] /// # #![allow(private_in_public)]
/// # #![allow(unused)] /// # #![allow(unused)]
/// #![deny(private_bounds)] /// #![deny(private_bounds)]
@ -4317,7 +4320,8 @@
/// the item actually provides. /// the item actually provides.
pub PRIVATE_BOUNDS, pub PRIVATE_BOUNDS,
Allow, Allow,
"private type in secondary interface of an item" "private type in secondary interface of an item",
@feature_gate = sym::type_privacy_lints;
} }
declare_lint! { declare_lint! {
@ -4327,6 +4331,7 @@
/// ### Example /// ### Example
/// ///
/// ```rust,compile_fail /// ```rust,compile_fail
/// # #![feature(type_privacy_lints)]
/// # #![allow(unused)] /// # #![allow(unused)]
/// #![deny(unnameable_types)] /// #![deny(unnameable_types)]
/// mod m { /// mod m {
@ -4345,5 +4350,6 @@
/// you can name the type `T` as well, this lint attempts to enforce this rule. /// you can name the type `T` as well, this lint attempts to enforce this rule.
pub UNNAMEABLE_TYPES, pub UNNAMEABLE_TYPES,
Allow, Allow,
"effective visibility of a type is larger than the area in which it can be named" "effective visibility of a type is larger than the area in which it can be named",
@feature_gate = sym::type_privacy_lints;
} }

View File

@ -4,6 +4,7 @@
use crate::ty::{TyCtxt, Visibility}; use crate::ty::{TyCtxt, Visibility};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir::def::DefKind;
use rustc_macros::HashStable; use rustc_macros::HashStable;
use rustc_query_system::ich::StableHashingContext; use rustc_query_system::ich::StableHashingContext;
use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID};
@ -148,13 +149,12 @@ pub fn update_eff_vis(
}; };
} }
pub fn check_invariants(&self, tcx: TyCtxt<'_>, early: bool) { pub fn check_invariants(&self, tcx: TyCtxt<'_>) {
if !cfg!(debug_assertions) { if !cfg!(debug_assertions) {
return; return;
} }
for (&def_id, ev) in &self.map { for (&def_id, ev) in &self.map {
// More direct visibility levels can never go farther than less direct ones, // More direct visibility levels can never go farther than less direct ones,
// neither of effective visibilities can go farther than nominal visibility,
// and all effective visibilities are larger or equal than private visibility. // and all effective visibilities are larger or equal than private visibility.
let private_vis = Visibility::Restricted(tcx.parent_module_from_def_id(def_id)); let private_vis = Visibility::Restricted(tcx.parent_module_from_def_id(def_id));
let span = tcx.def_span(def_id.to_def_id()); let span = tcx.def_span(def_id.to_def_id());
@ -175,17 +175,20 @@ pub fn check_invariants(&self, tcx: TyCtxt<'_>, early: bool) {
ev.reachable_through_impl_trait ev.reachable_through_impl_trait
); );
} }
let nominal_vis = tcx.visibility(def_id); // All effective visibilities except `reachable_through_impl_trait` are limited to
// FIXME: `rustc_privacy` is not yet updated for the new logic and can set // nominal visibility. For some items nominal visibility doesn't make sense so we
// effective visibilities that are larger than the nominal one. // don't check this condition for them.
if !nominal_vis.is_at_least(ev.reachable_through_impl_trait, tcx) && early { if !matches!(tcx.def_kind(def_id), DefKind::Impl { .. }) {
span_bug!( let nominal_vis = tcx.visibility(def_id);
span, if !nominal_vis.is_at_least(ev.reachable, tcx) {
"{:?}: reachable_through_impl_trait {:?} > nominal {:?}", span_bug!(
def_id, span,
ev.reachable_through_impl_trait, "{:?}: reachable {:?} > nominal {:?}",
nominal_vis def_id,
); ev.reachable,
nominal_vis
);
}
} }
} }
} }
@ -212,7 +215,7 @@ pub fn effective_vis_or_private(
pub fn update( pub fn update(
&mut self, &mut self,
id: Id, id: Id,
nominal_vis: Option<Visibility>, max_vis: Option<Visibility>,
lazy_private_vis: impl FnOnce() -> Visibility, lazy_private_vis: impl FnOnce() -> Visibility,
inherited_effective_vis: EffectiveVisibility, inherited_effective_vis: EffectiveVisibility,
level: Level, level: Level,
@ -236,8 +239,8 @@ pub fn update(
if !(inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level if !(inherited_effective_vis_at_prev_level == inherited_effective_vis_at_level
&& level != l) && level != l)
{ {
calculated_effective_vis = if let Some(nominal_vis) = nominal_vis && !nominal_vis.is_at_least(inherited_effective_vis_at_level, tcx) { calculated_effective_vis = if let Some(max_vis) = max_vis && !max_vis.is_at_least(inherited_effective_vis_at_level, tcx) {
nominal_vis max_vis
} else { } else {
inherited_effective_vis_at_level inherited_effective_vis_at_level
} }

View File

@ -73,14 +73,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
/// in `impl Trait`, see individual comments in `DefIdVisitorSkeleton::visit_ty`. /// in `impl Trait`, see individual comments in `DefIdVisitorSkeleton::visit_ty`.
trait DefIdVisitor<'tcx> { trait DefIdVisitor<'tcx> {
type BreakTy = (); type BreakTy = ();
const SHALLOW: bool = false;
const SKIP_ASSOC_TYS: bool = false;
fn tcx(&self) -> TyCtxt<'tcx>; fn tcx(&self) -> TyCtxt<'tcx>;
fn shallow(&self) -> bool {
false
}
fn skip_assoc_tys(&self) -> bool {
false
}
fn visit_def_id( fn visit_def_id(
&mut self, &mut self,
def_id: DefId, def_id: DefId,
@ -135,11 +131,7 @@ impl<'tcx, V> DefIdVisitorSkeleton<'_, 'tcx, V>
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<V::BreakTy> { fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<V::BreakTy> {
let TraitRef { def_id, substs, .. } = trait_ref; let TraitRef { def_id, substs, .. } = trait_ref;
self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref.print_only_trait_path())?; self.def_id_visitor.visit_def_id(def_id, "trait", &trait_ref.print_only_trait_path())?;
if self.def_id_visitor.shallow() { if V::SHALLOW { ControlFlow::Continue(()) } else { substs.visit_with(self) }
ControlFlow::Continue(())
} else {
substs.visit_with(self)
}
} }
fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> { fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<V::BreakTy> {
@ -158,7 +150,7 @@ fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<
) )
}; };
self.visit_trait(trait_ref)?; self.visit_trait(trait_ref)?;
if self.def_id_visitor.shallow() { if V::SHALLOW {
ControlFlow::Continue(()) ControlFlow::Continue(())
} else { } else {
assoc_substs.iter().try_for_each(|subst| subst.visit_with(self)) assoc_substs.iter().try_for_each(|subst| subst.visit_with(self))
@ -208,7 +200,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
| ty::Closure(def_id, ..) | ty::Closure(def_id, ..)
| ty::Generator(def_id, ..) => { | ty::Generator(def_id, ..) => {
self.def_id_visitor.visit_def_id(def_id, "type", &ty)?; self.def_id_visitor.visit_def_id(def_id, "type", &ty)?;
if self.def_id_visitor.shallow() { if V::SHALLOW {
return ControlFlow::Continue(()); return ControlFlow::Continue(());
} }
// Default type visitor doesn't visit signatures of fn types. // Default type visitor doesn't visit signatures of fn types.
@ -232,7 +224,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
self.def_id_visitor.visit_def_id(alias.def_id, "type alias", &ty); self.def_id_visitor.visit_def_id(alias.def_id, "type alias", &ty);
} }
ty::Alias(ty::Projection, proj) => { ty::Alias(ty::Projection, proj) => {
if self.def_id_visitor.skip_assoc_tys() { if V::SKIP_ASSOC_TYS {
// Visitors searching for minimal visibility/reachability want to // Visitors searching for minimal visibility/reachability want to
// conservatively approximate associated types like `<Type as Trait>::Alias` // conservatively approximate associated types like `<Type as Trait>::Alias`
// as visible/reachable even if both `Type` and `Trait` are private. // as visible/reachable even if both `Type` and `Trait` are private.
@ -244,7 +236,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
return self.visit_projection_ty(proj); return self.visit_projection_ty(proj);
} }
ty::Alias(ty::Inherent, data) => { ty::Alias(ty::Inherent, data) => {
if self.def_id_visitor.skip_assoc_tys() { if V::SKIP_ASSOC_TYS {
// Visitors searching for minimal visibility/reachability want to // Visitors searching for minimal visibility/reachability want to
// conservatively approximate associated types like `Type::Alias` // conservatively approximate associated types like `Type::Alias`
// as visible/reachable even if `Type` is private. // as visible/reachable even if `Type` is private.
@ -260,7 +252,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
)?; )?;
// This will also visit substs if necessary, so we don't need to recurse. // This will also visit substs if necessary, so we don't need to recurse.
return if self.def_id_visitor.shallow() { return if V::SHALLOW {
ControlFlow::Continue(()) ControlFlow::Continue(())
} else { } else {
data.substs.iter().try_for_each(|subst| subst.visit_with(self)) data.substs.iter().try_for_each(|subst| subst.visit_with(self))
@ -319,11 +311,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
} }
} }
if self.def_id_visitor.shallow() { if V::SHALLOW { ControlFlow::Continue(()) } else { ty.super_visit_with(self) }
ControlFlow::Continue(())
} else {
ty.super_visit_with(self)
}
} }
fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> { fn visit_const(&mut self, c: Const<'tcx>) -> ControlFlow<Self::BreakTy> {
@ -340,22 +328,20 @@ fn min(vis1: ty::Visibility, vis2: ty::Visibility, tcx: TyCtxt<'_>) -> ty::Visib
/// Visitor used to determine impl visibility and reachability. /// Visitor used to determine impl visibility and reachability.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
struct FindMin<'a, 'tcx, VL: VisibilityLike> { struct FindMin<'a, 'tcx, VL: VisibilityLike, const SHALLOW: bool> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
effective_visibilities: &'a EffectiveVisibilities, effective_visibilities: &'a EffectiveVisibilities,
min: VL, min: VL,
} }
impl<'a, 'tcx, VL: VisibilityLike> DefIdVisitor<'tcx> for FindMin<'a, 'tcx, VL> { impl<'a, 'tcx, VL: VisibilityLike, const SHALLOW: bool> DefIdVisitor<'tcx>
for FindMin<'a, 'tcx, VL, SHALLOW>
{
const SHALLOW: bool = SHALLOW;
const SKIP_ASSOC_TYS: bool = true;
fn tcx(&self) -> TyCtxt<'tcx> { fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx self.tcx
} }
fn shallow(&self) -> bool {
VL::SHALLOW
}
fn skip_assoc_tys(&self) -> bool {
true
}
fn visit_def_id( fn visit_def_id(
&mut self, &mut self,
def_id: DefId, def_id: DefId,
@ -371,17 +357,19 @@ fn visit_def_id(
trait VisibilityLike: Sized { trait VisibilityLike: Sized {
const MAX: Self; const MAX: Self;
const SHALLOW: bool = false; fn new_min<const SHALLOW: bool>(
fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self; find: &FindMin<'_, '_, Self, SHALLOW>,
def_id: LocalDefId,
) -> Self;
// Returns an over-approximation (`skip_assoc_tys` = true) of visibility due to // Returns an over-approximation (`SKIP_ASSOC_TYS` = true) of visibility due to
// associated types for which we can't determine visibility precisely. // associated types for which we can't determine visibility precisely.
fn of_impl( fn of_impl<const SHALLOW: bool>(
def_id: LocalDefId, def_id: LocalDefId,
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
effective_visibilities: &EffectiveVisibilities, effective_visibilities: &EffectiveVisibilities,
) -> Self { ) -> Self {
let mut find = FindMin { tcx, effective_visibilities, min: Self::MAX }; let mut find = FindMin::<_, SHALLOW> { tcx, effective_visibilities, min: Self::MAX };
find.visit(tcx.type_of(def_id).subst_identity()); find.visit(tcx.type_of(def_id).subst_identity());
if let Some(trait_ref) = tcx.impl_trait_ref(def_id) { if let Some(trait_ref) = tcx.impl_trait_ref(def_id) {
find.visit_trait(trait_ref.subst_identity()); find.visit_trait(trait_ref.subst_identity());
@ -391,49 +379,28 @@ fn of_impl(
} }
impl VisibilityLike for ty::Visibility { impl VisibilityLike for ty::Visibility {
const MAX: Self = ty::Visibility::Public; const MAX: Self = ty::Visibility::Public;
fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self { fn new_min<const SHALLOW: bool>(
find: &FindMin<'_, '_, Self, SHALLOW>,
def_id: LocalDefId,
) -> Self {
min(find.tcx.local_visibility(def_id), find.min, find.tcx) min(find.tcx.local_visibility(def_id), find.min, find.tcx)
} }
} }
struct NonShallowEffectiveVis(EffectiveVisibility); impl VisibilityLike for EffectiveVisibility {
const MAX: Self = EffectiveVisibility::from_vis(ty::Visibility::Public);
impl VisibilityLike for NonShallowEffectiveVis { fn new_min<const SHALLOW: bool>(
const MAX: Self = NonShallowEffectiveVis(EffectiveVisibility::from_vis(ty::Visibility::Public)); find: &FindMin<'_, '_, Self, SHALLOW>,
const SHALLOW: bool = false; def_id: LocalDefId,
) -> Self {
fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
let find = FindMin {
tcx: find.tcx,
effective_visibilities: find.effective_visibilities,
min: ShallowEffectiveVis(find.min.0),
};
NonShallowEffectiveVis(VisibilityLike::new_min(&find, def_id).0)
}
}
struct ShallowEffectiveVis(EffectiveVisibility);
impl VisibilityLike for ShallowEffectiveVis {
const MAX: Self = ShallowEffectiveVis(EffectiveVisibility::from_vis(ty::Visibility::Public));
// Type inference is very smart sometimes.
// It can make an impl reachable even some components of its type or trait are unreachable.
// E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
// can be usable from other crates (#57264). So we skip substs when calculating reachability
// and consider an impl reachable if its "shallow" type and trait are reachable.
//
// The assumption we make here is that type-inference won't let you use an impl without knowing
// both "shallow" version of its self type and "shallow" version of its trait if it exists
// (which require reaching the `DefId`s in them).
const SHALLOW: bool = true;
fn new_min(find: &FindMin<'_, '_, Self>, def_id: LocalDefId) -> Self {
let effective_vis = let effective_vis =
find.effective_visibilities.effective_vis(def_id).cloned().unwrap_or_else(|| { find.effective_visibilities.effective_vis(def_id).copied().unwrap_or_else(|| {
let private_vis = let private_vis =
ty::Visibility::Restricted(find.tcx.parent_module_from_def_id(def_id)); ty::Visibility::Restricted(find.tcx.parent_module_from_def_id(def_id));
EffectiveVisibility::from_vis(private_vis) EffectiveVisibility::from_vis(private_vis)
}); });
ShallowEffectiveVis(effective_vis.min(find.min.0, find.tcx)) effective_vis.min(find.min, find.tcx)
} }
} }
@ -492,14 +459,14 @@ fn update_eff_vis(
&mut self, &mut self,
def_id: LocalDefId, def_id: LocalDefId,
inherited_effective_vis: EffectiveVisibility, inherited_effective_vis: EffectiveVisibility,
nominal_vis: Option<ty::Visibility>, max_vis: Option<ty::Visibility>,
level: Level, level: Level,
) { ) {
let private_vis = ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id)); let private_vis = ty::Visibility::Restricted(self.tcx.parent_module_from_def_id(def_id));
if Some(private_vis) != nominal_vis { if max_vis != Some(private_vis) {
self.changed |= self.effective_visibilities.update( self.changed |= self.effective_visibilities.update(
def_id, def_id,
nominal_vis, max_vis,
|| private_vis, || private_vis,
inherited_effective_vis, inherited_effective_vis,
level, level,
@ -771,12 +738,21 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
} }
} }
hir::ItemKind::Impl(ref impl_) => { hir::ItemKind::Impl(ref impl_) => {
let item_ev = ShallowEffectiveVis::of_impl( // Type inference is very smart sometimes. It can make an impl reachable even some
// components of its type or trait are unreachable. E.g. methods of
// `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
// can be usable from other crates (#57264). So we skip substs when calculating
// reachability and consider an impl reachable if its "shallow" type and trait are
// reachable.
//
// The assumption we make here is that type-inference won't let you use an impl
// without knowing both "shallow" version of its self type and "shallow" version of
// its trait if it exists (which require reaching the `DefId`s in them).
let item_ev = EffectiveVisibility::of_impl::<true>(
item.owner_id.def_id, item.owner_id.def_id,
self.tcx, self.tcx,
&self.effective_visibilities, &self.effective_visibilities,
) );
.0;
self.update_eff_vis(item.owner_id.def_id, item_ev, None, Level::Direct); self.update_eff_vis(item.owner_id.def_id, item_ev, None, Level::Direct);
@ -784,9 +760,9 @@ fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
for impl_item_ref in impl_.items { for impl_item_ref in impl_.items {
let def_id = impl_item_ref.id.owner_id.def_id; let def_id = impl_item_ref.id.owner_id.def_id;
let nominal_vis = let max_vis =
impl_.of_trait.is_none().then(|| self.tcx.local_visibility(def_id)); impl_.of_trait.is_none().then(|| self.tcx.local_visibility(def_id));
self.update_eff_vis(def_id, item_ev, nominal_vis, Level::Direct); self.update_eff_vis(def_id, item_ev, max_vis, Level::Direct);
if let Some(impl_item_ev) = self.get(def_id) { if let Some(impl_item_ev) = self.get(def_id) {
self.reach(def_id, impl_item_ev).generics().predicates().ty(); self.reach(def_id, impl_item_ev).generics().predicates().ty();
@ -904,7 +880,12 @@ fn visit_def_id(
_descr: &dyn fmt::Display, _descr: &dyn fmt::Display,
) -> ControlFlow<Self::BreakTy> { ) -> ControlFlow<Self::BreakTy> {
if let Some(def_id) = def_id.as_local() { if let Some(def_id) = def_id.as_local() {
self.ev.update_eff_vis(def_id, self.effective_vis, None, self.level); // All effective visibilities except `reachable_through_impl_trait` are limited to
// nominal visibility. If any type or trait is leaked farther than that, it will
// produce type privacy errors on any use, so we don't consider it leaked.
let max_vis = (self.level != Level::ReachableThroughImplTrait)
.then(|| self.ev.tcx.local_visibility(def_id));
self.ev.update_eff_vis(def_id, self.effective_vis, max_vis, self.level);
} }
ControlFlow::Continue(()) ControlFlow::Continue(())
} }
@ -1876,10 +1857,9 @@ fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display)
return false; return false;
}; };
// FIXME: `Level::Reachable` should be taken instead of `Level::Reexported` let reachable_at_vis = *effective_vis.at_level(Level::Reachable);
let reexported_at_vis = *effective_vis.at_level(Level::Reexported);
if !vis.is_at_least(reexported_at_vis, self.tcx) { if !vis.is_at_least(reachable_at_vis, self.tcx) {
let lint = if self.in_primary_interface { let lint = if self.in_primary_interface {
lint::builtin::PRIVATE_INTERFACES lint::builtin::PRIVATE_INTERFACES
} else { } else {
@ -1896,7 +1876,7 @@ fn check_def_id(&mut self, def_id: DefId, kind: &str, descr: &dyn fmt::Display)
tcx: self.tcx, tcx: self.tcx,
}) })
.into(), .into(),
item_vis_descr: &vis_to_string(self.item_def_id, reexported_at_vis, self.tcx), item_vis_descr: &vis_to_string(self.item_def_id, reachable_at_vis, self.tcx),
ty_span: vis_span, ty_span: vis_span,
ty_kind: kind, ty_kind: kind,
ty_descr: descr.into(), ty_descr: descr.into(),
@ -2137,27 +2117,28 @@ pub fn check_item(&mut self, id: ItemId) {
DefKind::Impl { .. } => { DefKind::Impl { .. } => {
let item = tcx.hir().item(id); let item = tcx.hir().item(id);
if let hir::ItemKind::Impl(ref impl_) = item.kind { if let hir::ItemKind::Impl(ref impl_) = item.kind {
let impl_vis = let impl_vis = ty::Visibility::of_impl::<false>(
ty::Visibility::of_impl(item.owner_id.def_id, tcx, &Default::default()); item.owner_id.def_id,
tcx,
&Default::default(),
);
// we are using the non-shallow version here, unlike when building the // We are using the non-shallow version here, unlike when building the
// effective visisibilities table to avoid large number of false positives. // effective visisibilities table to avoid large number of false positives.
// For example: // For example in
// //
// impl From<Priv> for Pub { // impl From<Priv> for Pub {
// fn from(_: Priv) -> Pub {...} // fn from(_: Priv) -> Pub {...}
// } // }
// //
// lints shouldn't be emmited even `from` effective visibility // lints shouldn't be emmited even if `from` effective visibility
// is larger then `Priv` nominal visibility. // is larger than `Priv` nominal visibility and if `Priv` can leak
let impl_ev = Some( // in some scenarios due to type inference.
NonShallowEffectiveVis::of_impl( let impl_ev = Some(EffectiveVisibility::of_impl::<false>(
item.owner_id.def_id, item.owner_id.def_id,
tcx, tcx,
self.effective_visibilities, self.effective_visibilities,
) ));
.0,
);
// check that private components do not appear in the generics or predicates of inherent impls // check that private components do not appear in the generics or predicates of inherent impls
// this check is intentionally NOT performed for impls of traits, per #90586 // this check is intentionally NOT performed for impls of traits, per #90586
@ -2284,7 +2265,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
changed: false, changed: false,
}; };
visitor.effective_visibilities.check_invariants(tcx, true); visitor.effective_visibilities.check_invariants(tcx);
if visitor.impl_trait_pass { if visitor.impl_trait_pass {
// Underlying types of `impl Trait`s are marked as reachable unconditionally, // Underlying types of `impl Trait`s are marked as reachable unconditionally,
// so this pass doesn't need to be a part of the fixed point iteration below. // so this pass doesn't need to be a part of the fixed point iteration below.
@ -2301,7 +2282,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
break; break;
} }
} }
visitor.effective_visibilities.check_invariants(tcx, false); visitor.effective_visibilities.check_invariants(tcx);
let mut check_visitor = let mut check_visitor =
TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities }; TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities };

View File

@ -1558,6 +1558,7 @@
type_length_limit, type_length_limit,
type_macros, type_macros,
type_name, type_name,
type_privacy_lints,
u128, u128,
u16, u16,
u32, u32,

View File

@ -310,7 +310,7 @@ fn default() -> Self {
/// Real logic of both `Flatten` and `FlatMap` which simply delegate to /// Real logic of both `Flatten` and `FlatMap` which simply delegate to
/// this type. /// this type.
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
#[unstable(feature = "trusted_len", issue = "37572")] #[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
struct FlattenCompat<I, U> { struct FlattenCompat<I, U> {
iter: Fuse<I>, iter: Fuse<I>,
frontiter: Option<U>, frontiter: Option<U>,
@ -464,7 +464,7 @@ fn flatten<'a, T: IntoIterator, Acc, R: Try>(
} }
} }
#[unstable(feature = "trusted_len", issue = "37572")] #[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
impl<I, U> Iterator for FlattenCompat<I, U> impl<I, U> Iterator for FlattenCompat<I, U>
where where
I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>, I: Iterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
@ -579,7 +579,7 @@ fn last<U: Iterator>(last: Option<U::Item>, iter: U) -> Option<U::Item> {
} }
} }
#[unstable(feature = "trusted_len", issue = "37572")] #[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
impl<I, U> DoubleEndedIterator for FlattenCompat<I, U> impl<I, U> DoubleEndedIterator for FlattenCompat<I, U>
where where
I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>, I: DoubleEndedIterator<Item: IntoIterator<IntoIter = U, Item = U::Item>>,
@ -649,7 +649,7 @@ fn advance<U: DoubleEndedIterator>(n: usize, iter: &mut U) -> ControlFlow<(), us
} }
} }
#[unstable(feature = "trusted_len", issue = "37572")] #[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
unsafe impl<const N: usize, I, T> TrustedLen unsafe impl<const N: usize, I, T> TrustedLen
for FlattenCompat<I, <[T; N] as IntoIterator>::IntoIter> for FlattenCompat<I, <[T; N] as IntoIterator>::IntoIter>
where where
@ -657,7 +657,7 @@ unsafe impl<const N: usize, I, T> TrustedLen
{ {
} }
#[unstable(feature = "trusted_len", issue = "37572")] #[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
unsafe impl<'a, const N: usize, I, T> TrustedLen unsafe impl<'a, const N: usize, I, T> TrustedLen
for FlattenCompat<I, <&'a [T; N] as IntoIterator>::IntoIter> for FlattenCompat<I, <&'a [T; N] as IntoIterator>::IntoIter>
where where
@ -665,7 +665,7 @@ unsafe impl<'a, const N: usize, I, T> TrustedLen
{ {
} }
#[unstable(feature = "trusted_len", issue = "37572")] #[cfg_attr(bootstrap, unstable(feature = "trusted_len", issue = "37572"))]
unsafe impl<'a, const N: usize, I, T> TrustedLen unsafe impl<'a, const N: usize, I, T> TrustedLen
for FlattenCompat<I, <&'a mut [T; N] as IntoIterator>::IntoIter> for FlattenCompat<I, <&'a mut [T; N] as IntoIterator>::IntoIter>
where where

View File

@ -1,7 +1,7 @@
#![feature(inherent_associated_types)] #![feature(inherent_associated_types)]
#![feature(type_privacy_lints)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![crate_type = "lib"] #![crate_type = "lib"]
#![deny(private_in_public)] #![deny(private_in_public)]
#![warn(private_interfaces)] #![warn(private_interfaces)]

View File

@ -1,7 +1,7 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(generic_const_exprs)] #![feature(generic_const_exprs)]
#![feature(type_privacy_lints)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![warn(private_interfaces)] #![warn(private_interfaces)]
// In this test both old and new private-in-public diagnostic were emitted. // In this test both old and new private-in-public diagnostic were emitted.

View File

@ -1,3 +1,4 @@
#![feature(type_privacy_lints)]
#[warn(private_bounds)] #[warn(private_bounds)]
#[warn(private_interfaces)] #[warn(private_interfaces)]

View File

@ -1,5 +1,5 @@
error[E0445]: private trait `Foo` in public interface error[E0445]: private trait `Foo` in public interface
--> $DIR/E0445.rs:12:1 --> $DIR/E0445.rs:13:1
| |
LL | trait Foo { LL | trait Foo {
| --------- `Foo` declared as private | --------- `Foo` declared as private
@ -10,23 +10,23 @@ LL | pub trait Bar : Foo {}
warning: trait `Foo` is more private than the item `Bar` warning: trait `Foo` is more private than the item `Bar`
| |
note: trait `Bar` is reachable at visibility `pub` note: trait `Bar` is reachable at visibility `pub`
--> $DIR/E0445.rs:12:1 --> $DIR/E0445.rs:13:1
| |
LL | pub trait Bar : Foo {} LL | pub trait Bar : Foo {}
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
note: but trait `Foo` is only usable at visibility `pub(crate)` note: but trait `Foo` is only usable at visibility `pub(crate)`
--> $DIR/E0445.rs:8:1 --> $DIR/E0445.rs:9:1
| |
LL | trait Foo { LL | trait Foo {
| ^^^^^^^^^ | ^^^^^^^^^
note: the lint level is defined here note: the lint level is defined here
--> $DIR/E0445.rs:1:8 --> $DIR/E0445.rs:2:8
| |
LL | #[warn(private_bounds)] LL | #[warn(private_bounds)]
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error[E0445]: private trait `Foo` in public interface error[E0445]: private trait `Foo` in public interface
--> $DIR/E0445.rs:14:1 --> $DIR/E0445.rs:15:1
| |
LL | trait Foo { LL | trait Foo {
| --------- `Foo` declared as private | --------- `Foo` declared as private
@ -37,18 +37,18 @@ LL | pub struct Bar2<T: Foo>(pub T);
warning: trait `Foo` is more private than the item `Bar2` warning: trait `Foo` is more private than the item `Bar2`
| |
note: struct `Bar2` is reachable at visibility `pub` note: struct `Bar2` is reachable at visibility `pub`
--> $DIR/E0445.rs:14:1 --> $DIR/E0445.rs:15:1
| |
LL | pub struct Bar2<T: Foo>(pub T); LL | pub struct Bar2<T: Foo>(pub T);
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
note: but trait `Foo` is only usable at visibility `pub(crate)` note: but trait `Foo` is only usable at visibility `pub(crate)`
--> $DIR/E0445.rs:8:1 --> $DIR/E0445.rs:9:1
| |
LL | trait Foo { LL | trait Foo {
| ^^^^^^^^^ | ^^^^^^^^^
error[E0445]: private trait `Foo` in public interface error[E0445]: private trait `Foo` in public interface
--> $DIR/E0445.rs:16:1 --> $DIR/E0445.rs:17:1
| |
LL | trait Foo { LL | trait Foo {
| --------- `Foo` declared as private | --------- `Foo` declared as private
@ -59,12 +59,12 @@ LL | pub fn foo<T: Foo> (t: T) {}
warning: trait `Foo` is more private than the item `foo` warning: trait `Foo` is more private than the item `foo`
| |
note: function `foo` is reachable at visibility `pub` note: function `foo` is reachable at visibility `pub`
--> $DIR/E0445.rs:16:1 --> $DIR/E0445.rs:17:1
| |
LL | pub fn foo<T: Foo> (t: T) {} LL | pub fn foo<T: Foo> (t: T) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^
note: but trait `Foo` is only usable at visibility `pub(crate)` note: but trait `Foo` is only usable at visibility `pub(crate)`
--> $DIR/E0445.rs:8:1 --> $DIR/E0445.rs:9:1
| |
LL | trait Foo { LL | trait Foo {
| ^^^^^^^^^ | ^^^^^^^^^

View File

@ -0,0 +1,12 @@
// check-pass
#![warn(private_interfaces)] //~ WARN unknown lint
//~| WARN unknown lint
//~| WARN unknown lint
#![warn(private_bounds)] //~ WARN unknown lint
//~| WARN unknown lint
//~| WARN unknown lint
#![warn(unnameable_types)] //~ WARN unknown lint
//~| WARN unknown lint
//~| WARN unknown lint
fn main() {}

View File

@ -0,0 +1,93 @@
warning: unknown lint: `private_interfaces`
--> $DIR/feature-gate-type_privacy_lints.rs:3:1
|
LL | #![warn(private_interfaces)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `private_interfaces` lint is unstable
= note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
= note: `#[warn(unknown_lints)]` on by default
warning: unknown lint: `private_bounds`
--> $DIR/feature-gate-type_privacy_lints.rs:6:1
|
LL | #![warn(private_bounds)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `private_bounds` lint is unstable
= note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
warning: unknown lint: `unnameable_types`
--> $DIR/feature-gate-type_privacy_lints.rs:9:1
|
LL | #![warn(unnameable_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `unnameable_types` lint is unstable
= note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
warning: unknown lint: `private_interfaces`
--> $DIR/feature-gate-type_privacy_lints.rs:3:1
|
LL | #![warn(private_interfaces)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `private_interfaces` lint is unstable
= note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
warning: unknown lint: `private_bounds`
--> $DIR/feature-gate-type_privacy_lints.rs:6:1
|
LL | #![warn(private_bounds)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `private_bounds` lint is unstable
= note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
warning: unknown lint: `unnameable_types`
--> $DIR/feature-gate-type_privacy_lints.rs:9:1
|
LL | #![warn(unnameable_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `unnameable_types` lint is unstable
= note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
warning: unknown lint: `private_interfaces`
--> $DIR/feature-gate-type_privacy_lints.rs:3:1
|
LL | #![warn(private_interfaces)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `private_interfaces` lint is unstable
= note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
warning: unknown lint: `private_bounds`
--> $DIR/feature-gate-type_privacy_lints.rs:6:1
|
LL | #![warn(private_bounds)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `private_bounds` lint is unstable
= note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
warning: unknown lint: `unnameable_types`
--> $DIR/feature-gate-type_privacy_lints.rs:9:1
|
LL | #![warn(unnameable_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: the `unnameable_types` lint is unstable
= note: see issue #48054 <https://github.com/rust-lang/rust/issues/48054> for more information
= help: add `#![feature(type_privacy_lints)]` to the crate attributes to enable
warning: 9 warnings emitted

View File

@ -1,3 +1,4 @@
#![feature(type_privacy_lints)]
#![warn(private_bounds)] #![warn(private_bounds)]
// In this test both old and new private-in-public diagnostic were emitted. // In this test both old and new private-in-public diagnostic were emitted.

View File

@ -1,5 +1,5 @@
error[E0445]: private trait `Private<<Self as Public>::P, <Self as Public>::R>` in public interface error[E0445]: private trait `Private<<Self as Public>::P, <Self as Public>::R>` in public interface
--> $DIR/issue-18389.rs:13:1 --> $DIR/issue-18389.rs:14:1
| |
LL | trait Private<P, R> { LL | trait Private<P, R> {
| ------------------- `Private<<Self as Public>::P, <Self as Public>::R>` declared as private | ------------------- `Private<<Self as Public>::P, <Self as Public>::R>` declared as private
@ -14,7 +14,7 @@ LL | | > {
warning: trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public` warning: trait `Private<<Self as Public>::P, <Self as Public>::R>` is more private than the item `Public`
| |
note: trait `Public` is reachable at visibility `pub` note: trait `Public` is reachable at visibility `pub`
--> $DIR/issue-18389.rs:13:1 --> $DIR/issue-18389.rs:14:1
| |
LL | / pub trait Public: Private< LL | / pub trait Public: Private<
LL | | LL | |
@ -23,12 +23,12 @@ LL | | <Self as Public>::R
LL | | > { LL | | > {
| |_^ | |_^
note: but trait `Private<<Self as Public>::P, <Self as Public>::R>` is only usable at visibility `pub(crate)` note: but trait `Private<<Self as Public>::P, <Self as Public>::R>` is only usable at visibility `pub(crate)`
--> $DIR/issue-18389.rs:10:1 --> $DIR/issue-18389.rs:11:1
| |
LL | trait Private<P, R> { LL | trait Private<P, R> {
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^
note: the lint level is defined here note: the lint level is defined here
--> $DIR/issue-18389.rs:1:9 --> $DIR/issue-18389.rs:2:9
| |
LL | #![warn(private_bounds)] LL | #![warn(private_bounds)]
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^

View File

@ -6,7 +6,7 @@
mod m { mod m {
#[rustc_effective_visibility] #[rustc_effective_visibility]
struct Priv; struct Priv;
//~^ ERROR Direct: pub(self), Reexported: pub(self), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) //~^ ERROR not in the table
//~| ERROR not in the table //~| ERROR not in the table
#[rustc_effective_visibility] #[rustc_effective_visibility]

View File

@ -1,4 +1,4 @@
error: Direct: pub(self), Reexported: pub(self), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate) error: not in the table
--> $DIR/effective_visibilities_full_priv.rs:8:5 --> $DIR/effective_visibilities_full_priv.rs:8:5
| |
LL | struct Priv; LL | struct Priv;

View File

@ -1,6 +1,6 @@
#![feature(auto_traits)] #![feature(auto_traits)]
#![feature(negative_impls)] #![feature(negative_impls)]
#![feature(type_privacy_lints)]
#![deny(private_interfaces)] #![deny(private_interfaces)]
// In this test both old and new private-in-public diagnostic were emitted. // In this test both old and new private-in-public diagnostic were emitted.

View File

@ -1,4 +1,4 @@
#![allow(unused)] #![feature(type_privacy_lints)]
#![allow(private_in_public)] #![allow(private_in_public)]
#![deny(unnameable_types)] #![deny(unnameable_types)]

View File

@ -3,8 +3,8 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(generic_const_exprs)] #![feature(generic_const_exprs)]
#![feature(type_privacy_lints)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![warn(private_bounds)] #![warn(private_bounds)]
#![warn(private_interfaces)] #![warn(private_interfaces)]

View File

@ -2,8 +2,8 @@
#![crate_type = "lib"] #![crate_type = "lib"]
#![feature(generic_const_exprs)] #![feature(generic_const_exprs)]
#![feature(type_privacy_lints)]
#![allow(incomplete_features)] #![allow(incomplete_features)]
#![warn(private_bounds)] #![warn(private_bounds)]
// In this test both old and new private-in-public diagnostic were emitted. // In this test both old and new private-in-public diagnostic were emitted.

View File

@ -1,3 +1,4 @@
#![feature(type_privacy_lints)]
#![allow(non_camel_case_types)] // genus is always capitalized #![allow(non_camel_case_types)] // genus is always capitalized
#![warn(private_interfaces)] #![warn(private_interfaces)]
//~^ NOTE the lint level is defined here //~^ NOTE the lint level is defined here

View File

@ -1,5 +1,5 @@
error[E0446]: private type `Snail` in public interface error[E0446]: private type `Snail` in public interface
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:27:1 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:28:1
| |
LL | pub(crate) struct Snail; LL | pub(crate) struct Snail;
| ----------------------- `Snail` declared as private | ----------------------- `Snail` declared as private
@ -10,23 +10,23 @@ LL | pub type Helix_pomatia = Shell<Snail>;
warning: type `Snail` is more private than the item `Helix_pomatia` warning: type `Snail` is more private than the item `Helix_pomatia`
| |
note: type alias `Helix_pomatia` is reachable at visibility `pub` note: type alias `Helix_pomatia` is reachable at visibility `pub`
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:27:1 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:28:1
| |
LL | pub type Helix_pomatia = Shell<Snail>; LL | pub type Helix_pomatia = Shell<Snail>;
| ^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^
note: but type `Snail` is only usable at visibility `pub(crate)` note: but type `Snail` is only usable at visibility `pub(crate)`
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:9:1 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:10:1
| |
LL | pub(crate) struct Snail; LL | pub(crate) struct Snail;
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
note: the lint level is defined here note: the lint level is defined here
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:2:9 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:3:9
| |
LL | #![warn(private_interfaces)] LL | #![warn(private_interfaces)]
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
error[E0446]: crate-private type `Turtle` in public interface error[E0446]: crate-private type `Turtle` in public interface
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:31:1 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:32:1
| |
LL | pub(super) struct Turtle; LL | pub(super) struct Turtle;
| ------------------------ `Turtle` declared as crate-private | ------------------------ `Turtle` declared as crate-private
@ -37,18 +37,18 @@ LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
warning: type `Turtle` is more private than the item `Dermochelys_coriacea` warning: type `Turtle` is more private than the item `Dermochelys_coriacea`
| |
note: type alias `Dermochelys_coriacea` is reachable at visibility `pub` note: type alias `Dermochelys_coriacea` is reachable at visibility `pub`
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:31:1 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:32:1
| |
LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>; LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: but type `Turtle` is only usable at visibility `pub(crate)` note: but type `Turtle` is only usable at visibility `pub(crate)`
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:14:5 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:15:5
| |
LL | pub(super) struct Turtle; LL | pub(super) struct Turtle;
| ^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^
error[E0446]: private type `Tortoise` in public interface error[E0446]: private type `Tortoise` in public interface
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:35:1 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:36:1
| |
LL | struct Tortoise; LL | struct Tortoise;
| --------------- `Tortoise` declared as private | --------------- `Tortoise` declared as private
@ -59,12 +59,12 @@ LL | pub type Testudo_graeca = Shell<Tortoise>;
warning: type `Tortoise` is more private than the item `Testudo_graeca` warning: type `Tortoise` is more private than the item `Testudo_graeca`
| |
note: type alias `Testudo_graeca` is reachable at visibility `pub` note: type alias `Testudo_graeca` is reachable at visibility `pub`
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:35:1 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:36:1
| |
LL | pub type Testudo_graeca = Shell<Tortoise>; LL | pub type Testudo_graeca = Shell<Tortoise>;
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
note: but type `Tortoise` is only usable at visibility `pub(crate)` note: but type `Tortoise` is only usable at visibility `pub(crate)`
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:19:1 --> $DIR/issue-33174-restricted-type-in-public-interface.rs:20:1
| |
LL | struct Tortoise; LL | struct Tortoise;
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^