Private-in-public lints implementation
This commit is contained in:
parent
d0ee1908ed
commit
6d46382f6f
24 changed files with 893 additions and 85 deletions
|
@ -3372,7 +3372,9 @@ declare_lint_pass! {
|
||||||
OVERLAPPING_RANGE_ENDPOINTS,
|
OVERLAPPING_RANGE_ENDPOINTS,
|
||||||
PATTERNS_IN_FNS_WITHOUT_BODY,
|
PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||||
POINTER_STRUCTURAL_MATCH,
|
POINTER_STRUCTURAL_MATCH,
|
||||||
|
PRIVATE_BOUNDS,
|
||||||
PRIVATE_IN_PUBLIC,
|
PRIVATE_IN_PUBLIC,
|
||||||
|
PRIVATE_INTERFACES,
|
||||||
PROC_MACRO_BACK_COMPAT,
|
PROC_MACRO_BACK_COMPAT,
|
||||||
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
|
||||||
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
|
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
|
||||||
|
@ -3399,6 +3401,7 @@ declare_lint_pass! {
|
||||||
UNINHABITED_STATIC,
|
UNINHABITED_STATIC,
|
||||||
UNKNOWN_CRATE_TYPES,
|
UNKNOWN_CRATE_TYPES,
|
||||||
UNKNOWN_LINTS,
|
UNKNOWN_LINTS,
|
||||||
|
UNNAMEABLE_TYPES,
|
||||||
UNREACHABLE_CODE,
|
UNREACHABLE_CODE,
|
||||||
UNREACHABLE_PATTERNS,
|
UNREACHABLE_PATTERNS,
|
||||||
UNSAFE_OP_IN_UNSAFE_FN,
|
UNSAFE_OP_IN_UNSAFE_FN,
|
||||||
|
@ -4251,3 +4254,95 @@ declare_lint! {
|
||||||
Warn,
|
Warn,
|
||||||
"\"invalid_parameter\" isn't a valid argument for `#[macro_export]`",
|
"\"invalid_parameter\" isn't a valid argument for `#[macro_export]`",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `private_interfaces` lint detects types in a primary interface of an item,
|
||||||
|
/// that are more private than the item itself. Primary interface of an item is all
|
||||||
|
/// its interface except for bounds on generic parameters and where clauses.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust,compile_fail
|
||||||
|
/// # #![allow(unused)]
|
||||||
|
/// # #![allow(private_in_public)]
|
||||||
|
/// #![deny(private_interfaces)]
|
||||||
|
/// struct SemiPriv;
|
||||||
|
///
|
||||||
|
/// mod m1 {
|
||||||
|
/// struct Priv;
|
||||||
|
/// impl crate::SemiPriv {
|
||||||
|
/// pub fn f(_: Priv) {}
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// # fn main() {}
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// Having something private in primary interface guarantees that
|
||||||
|
/// the item will be unusable from outer modules due to type privacy.
|
||||||
|
pub PRIVATE_INTERFACES,
|
||||||
|
Allow,
|
||||||
|
"private type in primary interface of an item",
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `private_bounds` lint detects types in a secondary interface of an item,
|
||||||
|
/// that are more private than the item itself. Secondary interface of an item consists of
|
||||||
|
/// bounds on generic parameters and where clauses, including supertraits for trait items.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust,compile_fail
|
||||||
|
/// # #![allow(private_in_public)]
|
||||||
|
/// # #![allow(unused)]
|
||||||
|
/// #![deny(private_bounds)]
|
||||||
|
///
|
||||||
|
/// struct PrivTy;
|
||||||
|
/// pub struct S
|
||||||
|
/// where PrivTy:
|
||||||
|
/// {}
|
||||||
|
/// # fn main() {}
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// Having private types or traits in item bounds makes it less clear what interface
|
||||||
|
/// the item actually provides.
|
||||||
|
pub PRIVATE_BOUNDS,
|
||||||
|
Allow,
|
||||||
|
"private type in secondary interface of an item"
|
||||||
|
}
|
||||||
|
|
||||||
|
declare_lint! {
|
||||||
|
/// The `unnameable_types` lint detects types for which you can get objects of that type,
|
||||||
|
/// but cannot name the type itself.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
///
|
||||||
|
/// ```rust,compile_fail
|
||||||
|
/// # #![allow(unused)]
|
||||||
|
/// #![deny(unnameable_types)]
|
||||||
|
/// mod m {
|
||||||
|
/// pub struct S;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// pub fn get_voldemort() -> m::S { m::S }
|
||||||
|
/// # fn main() {}
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// {{produces}}
|
||||||
|
///
|
||||||
|
/// ### Explanation
|
||||||
|
///
|
||||||
|
/// It is often expected that if you can obtain an object of type `T`, then
|
||||||
|
/// you can name the type `T` as well, this lint attempts to enforce this rule.
|
||||||
|
pub UNNAMEABLE_TYPES,
|
||||||
|
Allow,
|
||||||
|
"effective visibility of a type is larger than the area in which it can be named"
|
||||||
|
}
|
||||||
|
|
|
@ -17,7 +17,14 @@ privacy_private_in_public_lint =
|
||||||
*[other] E0446
|
*[other] E0446
|
||||||
})
|
})
|
||||||
|
|
||||||
|
privacy_private_interface_or_bounds_lint = {$ty_kind} `{$ty_descr}` is more private than the item `{$item_descr}`
|
||||||
|
.item_note = {$item_kind} `{$item_descr}` is reachable at visibility `{$item_vis_descr}`
|
||||||
|
.ty_note = but {$ty_kind} `{$ty_descr}` is only usable at visibility `{$ty_vis_descr}`
|
||||||
|
|
||||||
privacy_report_effective_visibility = {$descr}
|
privacy_report_effective_visibility = {$descr}
|
||||||
|
|
||||||
|
privacy_unnameable_types_lint = {$kind} `{$descr}` is reachable but cannot be named
|
||||||
|
.label = reachable at visibility `{$reachable_vis}`, but can only be named at visibility `{$reexported_vis}`
|
||||||
|
|
||||||
privacy_unnamed_item_is_private = {$kind} is private
|
privacy_unnamed_item_is_private = {$kind} is private
|
||||||
.label = private {$kind}
|
.label = private {$kind}
|
||||||
|
|
|
@ -98,3 +98,32 @@ pub struct PrivateInPublicLint<'a> {
|
||||||
pub kind: &'a str,
|
pub kind: &'a str,
|
||||||
pub descr: DiagnosticArgFromDisplay<'a>,
|
pub descr: DiagnosticArgFromDisplay<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(privacy_unnameable_types_lint)]
|
||||||
|
pub struct UnnameableTypesLint<'a> {
|
||||||
|
#[label]
|
||||||
|
pub span: Span,
|
||||||
|
pub kind: &'a str,
|
||||||
|
pub descr: DiagnosticArgFromDisplay<'a>,
|
||||||
|
pub reachable_vis: &'a str,
|
||||||
|
pub reexported_vis: &'a str,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used for `private_interfaces` and `private_bounds` lints.
|
||||||
|
// They will replace private-in-public errors and compatibility lints in future.
|
||||||
|
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html for more details.
|
||||||
|
#[derive(LintDiagnostic)]
|
||||||
|
#[diag(privacy_private_interface_or_bounds_lint)]
|
||||||
|
pub struct PrivateInterfacesOrBoundsLint<'a> {
|
||||||
|
#[note(privacy_item_note)]
|
||||||
|
pub item_span: Span,
|
||||||
|
pub item_kind: &'a str,
|
||||||
|
pub item_descr: DiagnosticArgFromDisplay<'a>,
|
||||||
|
pub item_vis_descr: &'a str,
|
||||||
|
#[note(privacy_ty_note)]
|
||||||
|
pub ty_span: Span,
|
||||||
|
pub ty_kind: &'a str,
|
||||||
|
pub ty_descr: DiagnosticArgFromDisplay<'a>,
|
||||||
|
pub ty_vis_descr: &'a str,
|
||||||
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
|
||||||
use rustc_hir::intravisit::{self, Visitor};
|
use rustc_hir::intravisit::{self, Visitor};
|
||||||
use rustc_hir::{AssocItemKind, HirIdSet, ItemId, Node, PatKind};
|
use rustc_hir::{AssocItemKind, ForeignItemKind, HirIdSet, ItemId, Node, PatKind};
|
||||||
use rustc_middle::bug;
|
use rustc_middle::bug;
|
||||||
use rustc_middle::hir::nested_filter;
|
use rustc_middle::hir::nested_filter;
|
||||||
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
|
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
|
||||||
|
@ -42,8 +42,8 @@ use std::{fmt, mem};
|
||||||
|
|
||||||
use errors::{
|
use errors::{
|
||||||
FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface,
|
FieldIsPrivate, FieldIsPrivateLabel, FromPrivateDependencyInPublicInterface, InPublicInterface,
|
||||||
InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, ReportEffectiveVisibility,
|
InPublicInterfaceTraits, ItemIsPrivate, PrivateInPublicLint, PrivateInterfacesOrBoundsLint,
|
||||||
UnnamedItemIsPrivate,
|
ReportEffectiveVisibility, UnnameableTypesLint, UnnamedItemIsPrivate,
|
||||||
};
|
};
|
||||||
|
|
||||||
fluent_messages! { "../messages.ftl" }
|
fluent_messages! { "../messages.ftl" }
|
||||||
|
@ -52,6 +52,17 @@ fluent_messages! { "../messages.ftl" }
|
||||||
/// Generic infrastructure used to implement specific visitors below.
|
/// Generic infrastructure used to implement specific visitors below.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
struct LazyDefPathStr<'tcx> {
|
||||||
|
def_id: DefId,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.tcx.def_path_str(self.def_id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Implemented to visit all `DefId`s in a type.
|
/// Implemented to visit all `DefId`s in a type.
|
||||||
/// Visiting `DefId`s is useful because visibilities and reachabilities are attached to them.
|
/// Visiting `DefId`s is useful because visibilities and reachabilities are attached to them.
|
||||||
/// The idea is to visit "all components of a type", as documented in
|
/// The idea is to visit "all components of a type", as documented in
|
||||||
|
@ -259,16 +270,6 @@ where
|
||||||
&LazyDefPathStr { def_id: data.def_id, tcx },
|
&LazyDefPathStr { def_id: data.def_id, tcx },
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
struct LazyDefPathStr<'tcx> {
|
|
||||||
def_id: DefId,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
}
|
|
||||||
impl<'tcx> fmt::Display for LazyDefPathStr<'tcx> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
write!(f, "{}", self.tcx.def_path_str(self.def_id))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 self.def_id_visitor.shallow() {
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
|
@ -409,8 +410,25 @@ impl VisibilityLike for ty::Visibility {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VisibilityLike for EffectiveVisibility {
|
struct NonShallowEffectiveVis(EffectiveVisibility);
|
||||||
const MAX: Self = EffectiveVisibility::from_vis(ty::Visibility::Public);
|
|
||||||
|
impl VisibilityLike for NonShallowEffectiveVis {
|
||||||
|
const MAX: Self = NonShallowEffectiveVis(EffectiveVisibility::from_vis(ty::Visibility::Public));
|
||||||
|
const SHALLOW: bool = false;
|
||||||
|
|
||||||
|
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.
|
// Type inference is very smart sometimes.
|
||||||
// It can make an impl reachable even some components of its type or trait are unreachable.
|
// 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> { ... }`
|
// E.g. methods of `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
|
||||||
|
@ -429,7 +447,7 @@ impl VisibilityLike for EffectiveVisibility {
|
||||||
EffectiveVisibility::from_vis(private_vis)
|
EffectiveVisibility::from_vis(private_vis)
|
||||||
});
|
});
|
||||||
|
|
||||||
effective_vis.min(find.min, find.tcx)
|
ShallowEffectiveVis(effective_vis.min(find.min.0, find.tcx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -767,11 +785,13 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hir::ItemKind::Impl(ref impl_) => {
|
hir::ItemKind::Impl(ref impl_) => {
|
||||||
let item_ev = EffectiveVisibility::of_impl(
|
let item_ev = ShallowEffectiveVis::of_impl(
|
||||||
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);
|
||||||
|
|
||||||
self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty().trait_ref();
|
self.reach(item.owner_id.def_id, item_ev).generics().predicates().ty().trait_ref();
|
||||||
|
@ -912,6 +932,21 @@ pub struct TestReachabilityVisitor<'tcx, 'a> {
|
||||||
effective_visibilities: &'a EffectiveVisibilities,
|
effective_visibilities: &'a EffectiveVisibilities,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn vis_to_string<'tcx>(def_id: LocalDefId, vis: ty::Visibility, tcx: TyCtxt<'tcx>) -> String {
|
||||||
|
match vis {
|
||||||
|
ty::Visibility::Restricted(restricted_id) => {
|
||||||
|
if restricted_id.is_top_level_module() {
|
||||||
|
"pub(crate)".to_string()
|
||||||
|
} else if restricted_id == tcx.parent_module_from_def_id(def_id) {
|
||||||
|
"pub(self)".to_string()
|
||||||
|
} else {
|
||||||
|
format!("pub({})", tcx.item_name(restricted_id.to_def_id()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ty::Visibility::Public => "pub".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
|
impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
|
||||||
fn effective_visibility_diagnostic(&mut self, def_id: LocalDefId) {
|
fn effective_visibility_diagnostic(&mut self, def_id: LocalDefId) {
|
||||||
if self.tcx.has_attr(def_id, sym::rustc_effective_visibility) {
|
if self.tcx.has_attr(def_id, sym::rustc_effective_visibility) {
|
||||||
|
@ -919,18 +954,7 @@ impl<'tcx, 'a> TestReachabilityVisitor<'tcx, 'a> {
|
||||||
let span = self.tcx.def_span(def_id.to_def_id());
|
let span = self.tcx.def_span(def_id.to_def_id());
|
||||||
if let Some(effective_vis) = self.effective_visibilities.effective_vis(def_id) {
|
if let Some(effective_vis) = self.effective_visibilities.effective_vis(def_id) {
|
||||||
for level in Level::all_levels() {
|
for level in Level::all_levels() {
|
||||||
let vis_str = match effective_vis.at_level(level) {
|
let vis_str = vis_to_string(def_id, *effective_vis.at_level(level), self.tcx);
|
||||||
ty::Visibility::Restricted(restricted_id) => {
|
|
||||||
if restricted_id.is_top_level_module() {
|
|
||||||
"pub(crate)".to_string()
|
|
||||||
} else if *restricted_id == self.tcx.parent_module_from_def_id(def_id) {
|
|
||||||
"pub(self)".to_string()
|
|
||||||
} else {
|
|
||||||
format!("pub({})", self.tcx.item_name(restricted_id.to_def_id()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ty::Visibility::Public => "pub".to_string(),
|
|
||||||
};
|
|
||||||
if level != Level::Direct {
|
if level != Level::Direct {
|
||||||
error_msg.push_str(", ");
|
error_msg.push_str(", ");
|
||||||
}
|
}
|
||||||
|
@ -1745,12 +1769,15 @@ struct SearchInterfaceForPrivateItemsVisitor<'tcx> {
|
||||||
item_def_id: LocalDefId,
|
item_def_id: LocalDefId,
|
||||||
/// The visitor checks that each component type is at least this visible.
|
/// The visitor checks that each component type is at least this visible.
|
||||||
required_visibility: ty::Visibility,
|
required_visibility: ty::Visibility,
|
||||||
|
required_effective_vis: Option<EffectiveVisibility>,
|
||||||
has_old_errors: bool,
|
has_old_errors: bool,
|
||||||
in_assoc_ty: bool,
|
in_assoc_ty: bool,
|
||||||
|
in_primary_interface: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
||||||
fn generics(&mut self) -> &mut Self {
|
fn generics(&mut self) -> &mut Self {
|
||||||
|
self.in_primary_interface = true;
|
||||||
for param in &self.tcx.generics_of(self.item_def_id).params {
|
for param in &self.tcx.generics_of(self.item_def_id).params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => {}
|
GenericParamDefKind::Lifetime => {}
|
||||||
|
@ -1769,6 +1796,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn predicates(&mut self) -> &mut Self {
|
fn predicates(&mut self) -> &mut Self {
|
||||||
|
self.in_primary_interface = false;
|
||||||
// N.B., we use `explicit_predicates_of` and not `predicates_of`
|
// N.B., we use `explicit_predicates_of` and not `predicates_of`
|
||||||
// because we don't want to report privacy errors due to where
|
// because we don't want to report privacy errors due to where
|
||||||
// clauses that the compiler inferred. We only want to
|
// clauses that the compiler inferred. We only want to
|
||||||
|
@ -1780,6 +1808,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bounds(&mut self) -> &mut Self {
|
fn bounds(&mut self) -> &mut Self {
|
||||||
|
self.in_primary_interface = false;
|
||||||
self.visit_predicates(ty::GenericPredicates {
|
self.visit_predicates(ty::GenericPredicates {
|
||||||
parent: None,
|
parent: None,
|
||||||
predicates: self.tcx.explicit_item_bounds(self.item_def_id).skip_binder(),
|
predicates: self.tcx.explicit_item_bounds(self.item_def_id).skip_binder(),
|
||||||
|
@ -1788,6 +1817,7 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty(&mut self) -> &mut Self {
|
fn ty(&mut self) -> &mut Self {
|
||||||
|
self.in_primary_interface = true;
|
||||||
self.visit(self.tcx.type_of(self.item_def_id).subst_identity());
|
self.visit(self.tcx.type_of(self.item_def_id).subst_identity());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
@ -1811,8 +1841,10 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let vis = self.tcx.local_visibility(local_def_id);
|
let vis = self.tcx.local_visibility(local_def_id);
|
||||||
|
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 !vis.is_at_least(self.required_visibility, self.tcx) {
|
||||||
let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_def_id);
|
|
||||||
let vis_descr = match vis {
|
let vis_descr = match vis {
|
||||||
ty::Visibility::Public => "public",
|
ty::Visibility::Public => "public",
|
||||||
ty::Visibility::Restricted(vis_def_id) => {
|
ty::Visibility::Restricted(vis_def_id) => {
|
||||||
|
@ -1825,12 +1857,11 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let span = self.tcx.def_span(self.item_def_id.to_def_id());
|
|
||||||
if self.has_old_errors
|
if self.has_old_errors
|
||||||
|| self.in_assoc_ty
|
|| self.in_assoc_ty
|
||||||
|| self.tcx.resolutions(()).has_pub_restricted
|
|| self.tcx.resolutions(()).has_pub_restricted
|
||||||
{
|
{
|
||||||
let vis_span = self.tcx.def_span(def_id);
|
|
||||||
if kind == "trait" {
|
if kind == "trait" {
|
||||||
self.tcx.sess.emit_err(InPublicInterfaceTraits {
|
self.tcx.sess.emit_err(InPublicInterfaceTraits {
|
||||||
span,
|
span,
|
||||||
|
@ -1858,6 +1889,39 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let Some(effective_vis) = self.required_effective_vis else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME: `Level::Reachable` should be taken instead of `Level::Reexported`
|
||||||
|
let reexported_at_vis = *effective_vis.at_level(Level::Reexported);
|
||||||
|
|
||||||
|
if !vis.is_at_least(reexported_at_vis, self.tcx) {
|
||||||
|
let lint = if self.in_primary_interface {
|
||||||
|
lint::builtin::PRIVATE_INTERFACES
|
||||||
|
} else {
|
||||||
|
lint::builtin::PRIVATE_BOUNDS
|
||||||
|
};
|
||||||
|
self.tcx.emit_lint(
|
||||||
|
lint,
|
||||||
|
hir_id,
|
||||||
|
PrivateInterfacesOrBoundsLint {
|
||||||
|
item_span: span,
|
||||||
|
item_kind: self.tcx.def_descr(self.item_def_id.to_def_id()),
|
||||||
|
item_descr: (&LazyDefPathStr {
|
||||||
|
def_id: self.item_def_id.to_def_id(),
|
||||||
|
tcx: self.tcx,
|
||||||
|
})
|
||||||
|
.into(),
|
||||||
|
item_vis_descr: &vis_to_string(self.item_def_id, reexported_at_vis, self.tcx),
|
||||||
|
ty_span: vis_span,
|
||||||
|
ty_kind: kind,
|
||||||
|
ty_descr: descr.into(),
|
||||||
|
ty_vis_descr: &vis_to_string(local_def_id, vis, self.tcx),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1891,25 +1955,55 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PrivateItemsInPublicInterfacesChecker<'tcx> {
|
struct PrivateItemsInPublicInterfacesChecker<'tcx, 'a> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
old_error_set_ancestry: HirIdSet,
|
old_error_set_ancestry: HirIdSet,
|
||||||
|
effective_visibilities: &'a EffectiveVisibilities,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
|
impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
|
||||||
fn check(
|
fn check(
|
||||||
&self,
|
&self,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
required_visibility: ty::Visibility,
|
required_visibility: ty::Visibility,
|
||||||
|
required_effective_vis: Option<EffectiveVisibility>,
|
||||||
) -> SearchInterfaceForPrivateItemsVisitor<'tcx> {
|
) -> SearchInterfaceForPrivateItemsVisitor<'tcx> {
|
||||||
SearchInterfaceForPrivateItemsVisitor {
|
SearchInterfaceForPrivateItemsVisitor {
|
||||||
tcx: self.tcx,
|
tcx: self.tcx,
|
||||||
item_def_id: def_id,
|
item_def_id: def_id,
|
||||||
required_visibility,
|
required_visibility,
|
||||||
|
required_effective_vis,
|
||||||
has_old_errors: self
|
has_old_errors: self
|
||||||
.old_error_set_ancestry
|
.old_error_set_ancestry
|
||||||
.contains(&self.tcx.hir().local_def_id_to_hir_id(def_id)),
|
.contains(&self.tcx.hir().local_def_id_to_hir_id(def_id)),
|
||||||
in_assoc_ty: false,
|
in_assoc_ty: false,
|
||||||
|
in_primary_interface: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_unnameable(&self, def_id: LocalDefId, effective_vis: Option<EffectiveVisibility>) {
|
||||||
|
let Some(effective_vis) = effective_vis else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let reexported_at_vis = effective_vis.at_level(Level::Reexported);
|
||||||
|
let reachable_at_vis = effective_vis.at_level(Level::Reachable);
|
||||||
|
|
||||||
|
if reexported_at_vis != reachable_at_vis {
|
||||||
|
let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
|
let span = self.tcx.def_span(def_id.to_def_id());
|
||||||
|
self.tcx.emit_spanned_lint(
|
||||||
|
lint::builtin::UNNAMEABLE_TYPES,
|
||||||
|
hir_id,
|
||||||
|
span,
|
||||||
|
UnnameableTypesLint {
|
||||||
|
span,
|
||||||
|
kind: self.tcx.def_descr(def_id.to_def_id()),
|
||||||
|
descr: (&LazyDefPathStr { def_id: def_id.to_def_id(), tcx: self.tcx }).into(),
|
||||||
|
reachable_vis: &vis_to_string(def_id, *reachable_at_vis, self.tcx),
|
||||||
|
reexported_vis: &vis_to_string(def_id, *reexported_at_vis, self.tcx),
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1918,13 +2012,19 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
assoc_item_kind: AssocItemKind,
|
assoc_item_kind: AssocItemKind,
|
||||||
vis: ty::Visibility,
|
vis: ty::Visibility,
|
||||||
|
effective_vis: Option<EffectiveVisibility>,
|
||||||
) {
|
) {
|
||||||
let mut check = self.check(def_id, vis);
|
let mut check = self.check(def_id, vis, effective_vis);
|
||||||
|
|
||||||
let (check_ty, is_assoc_ty) = match assoc_item_kind {
|
let (check_ty, is_assoc_ty) = match assoc_item_kind {
|
||||||
AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false),
|
AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false),
|
||||||
AssocItemKind::Type => (self.tcx.defaultness(def_id).has_value(), true),
|
AssocItemKind::Type => (self.tcx.defaultness(def_id).has_value(), true),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if is_assoc_ty {
|
||||||
|
self.check_unnameable(def_id, self.get(def_id));
|
||||||
|
}
|
||||||
|
|
||||||
check.in_assoc_ty = is_assoc_ty;
|
check.in_assoc_ty = is_assoc_ty;
|
||||||
check.generics().predicates();
|
check.generics().predicates();
|
||||||
if check_ty {
|
if check_ty {
|
||||||
|
@ -1932,50 +2032,72 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get(&self, def_id: LocalDefId) -> Option<EffectiveVisibility> {
|
||||||
|
self.effective_visibilities.effective_vis(def_id).copied()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn check_item(&mut self, id: ItemId) {
|
pub fn check_item(&mut self, id: ItemId) {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let def_id = id.owner_id.def_id;
|
let def_id = id.owner_id.def_id;
|
||||||
let item_visibility = tcx.local_visibility(def_id);
|
let item_visibility = tcx.local_visibility(def_id);
|
||||||
|
let effective_vis = self.get(def_id);
|
||||||
let def_kind = tcx.def_kind(def_id);
|
let def_kind = tcx.def_kind(def_id);
|
||||||
|
|
||||||
match def_kind {
|
match def_kind {
|
||||||
DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => {
|
DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => {
|
||||||
self.check(def_id, item_visibility).generics().predicates().ty();
|
if let DefKind::TyAlias = def_kind {
|
||||||
|
self.check_unnameable(def_id, effective_vis);
|
||||||
|
}
|
||||||
|
self.check(def_id, item_visibility, effective_vis).generics().predicates().ty();
|
||||||
}
|
}
|
||||||
DefKind::OpaqueTy => {
|
DefKind::OpaqueTy => {
|
||||||
// `ty()` for opaque types is the underlying type,
|
// `ty()` for opaque types is the underlying type,
|
||||||
// it's not a part of interface, so we skip it.
|
// it's not a part of interface, so we skip it.
|
||||||
self.check(def_id, item_visibility).generics().bounds();
|
self.check(def_id, item_visibility, effective_vis).generics().bounds();
|
||||||
}
|
}
|
||||||
DefKind::Trait => {
|
DefKind::Trait => {
|
||||||
let item = tcx.hir().item(id);
|
let item = tcx.hir().item(id);
|
||||||
if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind {
|
if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind {
|
||||||
self.check(item.owner_id.def_id, item_visibility).generics().predicates();
|
self.check_unnameable(item.owner_id.def_id, effective_vis);
|
||||||
|
|
||||||
|
self.check(item.owner_id.def_id, item_visibility, effective_vis)
|
||||||
|
.generics()
|
||||||
|
.predicates();
|
||||||
|
|
||||||
for trait_item_ref in trait_item_refs {
|
for trait_item_ref in trait_item_refs {
|
||||||
self.check_assoc_item(
|
self.check_assoc_item(
|
||||||
trait_item_ref.id.owner_id.def_id,
|
trait_item_ref.id.owner_id.def_id,
|
||||||
trait_item_ref.kind,
|
trait_item_ref.kind,
|
||||||
item_visibility,
|
item_visibility,
|
||||||
|
effective_vis,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let AssocItemKind::Type = trait_item_ref.kind {
|
if let AssocItemKind::Type = trait_item_ref.kind {
|
||||||
self.check(trait_item_ref.id.owner_id.def_id, item_visibility).bounds();
|
self.check(
|
||||||
|
trait_item_ref.id.owner_id.def_id,
|
||||||
|
item_visibility,
|
||||||
|
effective_vis,
|
||||||
|
)
|
||||||
|
.bounds();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefKind::TraitAlias => {
|
DefKind::TraitAlias => {
|
||||||
self.check(def_id, item_visibility).generics().predicates();
|
self.check(def_id, item_visibility, effective_vis).generics().predicates();
|
||||||
}
|
}
|
||||||
DefKind::Enum => {
|
DefKind::Enum => {
|
||||||
let item = tcx.hir().item(id);
|
let item = tcx.hir().item(id);
|
||||||
if let hir::ItemKind::Enum(ref def, _) = item.kind {
|
if let hir::ItemKind::Enum(ref def, _) = item.kind {
|
||||||
self.check(item.owner_id.def_id, item_visibility).generics().predicates();
|
self.check_unnameable(item.owner_id.def_id, effective_vis);
|
||||||
|
|
||||||
|
self.check(item.owner_id.def_id, item_visibility, effective_vis)
|
||||||
|
.generics()
|
||||||
|
.predicates();
|
||||||
|
|
||||||
for variant in def.variants {
|
for variant in def.variants {
|
||||||
for field in variant.data.fields() {
|
for field in variant.data.fields() {
|
||||||
self.check(field.def_id, item_visibility).ty();
|
self.check(field.def_id, item_visibility, effective_vis).ty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1985,8 +2107,16 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
|
||||||
let item = tcx.hir().item(id);
|
let item = tcx.hir().item(id);
|
||||||
if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
|
if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
|
||||||
for foreign_item in items {
|
for foreign_item in items {
|
||||||
let vis = tcx.local_visibility(foreign_item.id.owner_id.def_id);
|
let foreign_item = tcx.hir().foreign_item(foreign_item.id);
|
||||||
self.check(foreign_item.id.owner_id.def_id, vis)
|
|
||||||
|
let ev = self.get(foreign_item.owner_id.def_id);
|
||||||
|
let vis = tcx.local_visibility(foreign_item.owner_id.def_id);
|
||||||
|
|
||||||
|
if let ForeignItemKind::Type = foreign_item.kind {
|
||||||
|
self.check_unnameable(foreign_item.owner_id.def_id, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.check(foreign_item.owner_id.def_id, vis, ev)
|
||||||
.generics()
|
.generics()
|
||||||
.predicates()
|
.predicates()
|
||||||
.ty();
|
.ty();
|
||||||
|
@ -1999,11 +2129,21 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
|
||||||
if let hir::ItemKind::Struct(ref struct_def, _)
|
if let hir::ItemKind::Struct(ref struct_def, _)
|
||||||
| hir::ItemKind::Union(ref struct_def, _) = item.kind
|
| hir::ItemKind::Union(ref struct_def, _) = item.kind
|
||||||
{
|
{
|
||||||
self.check(item.owner_id.def_id, item_visibility).generics().predicates();
|
self.check_unnameable(item.owner_id.def_id, effective_vis);
|
||||||
|
self.check(item.owner_id.def_id, item_visibility, effective_vis)
|
||||||
|
.generics()
|
||||||
|
.predicates();
|
||||||
|
|
||||||
for field in struct_def.fields() {
|
for field in struct_def.fields() {
|
||||||
let field_visibility = tcx.local_visibility(field.def_id);
|
let field_visibility = tcx.local_visibility(field.def_id);
|
||||||
self.check(field.def_id, min(item_visibility, field_visibility, tcx)).ty();
|
let field_ev = self.get(field.def_id);
|
||||||
|
|
||||||
|
self.check(
|
||||||
|
field.def_id,
|
||||||
|
min(item_visibility, field_visibility, tcx),
|
||||||
|
field_ev,
|
||||||
|
)
|
||||||
|
.ty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2016,10 +2156,30 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
|
||||||
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(item.owner_id.def_id, tcx, &Default::default());
|
ty::Visibility::of_impl(item.owner_id.def_id, tcx, &Default::default());
|
||||||
|
|
||||||
|
// we are using the non-shallow version here, unlike when building the
|
||||||
|
// effective visisibilities table to avoid large number of false positives.
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// impl From<Priv> for Pub {
|
||||||
|
// fn from(_: Priv) -> Pub {...}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// lints shouldn't be emmited even `from` effective visibility
|
||||||
|
// is larger then `Priv` nominal visibility.
|
||||||
|
let impl_ev = Some(
|
||||||
|
NonShallowEffectiveVis::of_impl(
|
||||||
|
item.owner_id.def_id,
|
||||||
|
tcx,
|
||||||
|
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
|
||||||
if impl_.of_trait.is_none() {
|
if impl_.of_trait.is_none() {
|
||||||
self.check(item.owner_id.def_id, impl_vis).generics().predicates();
|
self.check(item.owner_id.def_id, impl_vis, impl_ev).generics().predicates();
|
||||||
}
|
}
|
||||||
for impl_item_ref in impl_.items {
|
for impl_item_ref in impl_.items {
|
||||||
let impl_item_vis = if impl_.of_trait.is_none() {
|
let impl_item_vis = if impl_.of_trait.is_none() {
|
||||||
|
@ -2031,10 +2191,18 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx> {
|
||||||
} else {
|
} else {
|
||||||
impl_vis
|
impl_vis
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let impl_item_ev = if impl_.of_trait.is_none() {
|
||||||
|
self.get(impl_item_ref.id.owner_id.def_id)
|
||||||
|
} else {
|
||||||
|
impl_ev
|
||||||
|
};
|
||||||
|
|
||||||
self.check_assoc_item(
|
self.check_assoc_item(
|
||||||
impl_item_ref.id.owner_id.def_id,
|
impl_item_ref.id.owner_id.def_id,
|
||||||
impl_item_ref.kind,
|
impl_item_ref.kind,
|
||||||
impl_item_vis,
|
impl_item_vis,
|
||||||
|
impl_item_ev,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2186,7 +2354,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for private types and traits in public interfaces.
|
// Check for private types and traits in public interfaces.
|
||||||
let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, old_error_set_ancestry };
|
let mut checker = PrivateItemsInPublicInterfacesChecker {
|
||||||
|
tcx,
|
||||||
|
old_error_set_ancestry,
|
||||||
|
effective_visibilities,
|
||||||
|
};
|
||||||
|
|
||||||
for id in tcx.hir().items() {
|
for id in tcx.hir().items() {
|
||||||
checker.check_item(id);
|
checker.check_item(id);
|
||||||
|
|
|
@ -3,6 +3,11 @@
|
||||||
#![crate_type = "lib"]
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
#![deny(private_in_public)]
|
#![deny(private_in_public)]
|
||||||
|
#![warn(private_interfaces)]
|
||||||
|
|
||||||
|
// In this test both old and new private-in-public diagnostic were emitted.
|
||||||
|
// Old diagnostic will be deleted soon.
|
||||||
|
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
|
||||||
|
|
||||||
pub type PubAlias0 = PubTy::PrivAssocTy;
|
pub type PubAlias0 = PubTy::PrivAssocTy;
|
||||||
//~^ ERROR private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
|
//~^ ERROR private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
|
error: private associated type `PubTy::PrivAssocTy` in public interface (error E0446)
|
||||||
--> $DIR/private-in-public.rs:7:1
|
--> $DIR/private-in-public.rs:12:1
|
||||||
|
|
|
|
||||||
LL | pub type PubAlias0 = PubTy::PrivAssocTy;
|
LL | pub type PubAlias0 = PubTy::PrivAssocTy;
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -12,8 +12,26 @@ note: the lint level is defined here
|
||||||
LL | #![deny(private_in_public)]
|
LL | #![deny(private_in_public)]
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
warning: associated type `PubTy::PrivAssocTy` is more private than the item `PubAlias0`
|
||||||
|
|
|
||||||
|
note: type alias `PubAlias0` is reachable at visibility `pub`
|
||||||
|
--> $DIR/private-in-public.rs:12:1
|
||||||
|
|
|
||||||
|
LL | pub type PubAlias0 = PubTy::PrivAssocTy;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but associated type `PubTy::PrivAssocTy` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/private-in-public.rs:24:5
|
||||||
|
|
|
||||||
|
LL | type PrivAssocTy = ();
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/private-in-public.rs:6:9
|
||||||
|
|
|
||||||
|
LL | #![warn(private_interfaces)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: private type `PrivTy` in public interface (error E0446)
|
error: private type `PrivTy` in public interface (error E0446)
|
||||||
--> $DIR/private-in-public.rs:10:1
|
--> $DIR/private-in-public.rs:15:1
|
||||||
|
|
|
|
||||||
LL | pub type PubAlias1 = PrivTy::PubAssocTy;
|
LL | pub type PubAlias1 = PrivTy::PubAssocTy;
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -21,8 +39,21 @@ LL | pub type PubAlias1 = PrivTy::PubAssocTy;
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
|
|
||||||
|
warning: type `PrivTy` is more private than the item `PubAlias1`
|
||||||
|
|
|
||||||
|
note: type alias `PubAlias1` is reachable at visibility `pub`
|
||||||
|
--> $DIR/private-in-public.rs:15:1
|
||||||
|
|
|
||||||
|
LL | pub type PubAlias1 = PrivTy::PubAssocTy;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but type `PrivTy` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/private-in-public.rs:28:1
|
||||||
|
|
|
||||||
|
LL | struct PrivTy;
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: private type `PrivTy` in public interface (error E0446)
|
error: private type `PrivTy` in public interface (error E0446)
|
||||||
--> $DIR/private-in-public.rs:13:1
|
--> $DIR/private-in-public.rs:18:1
|
||||||
|
|
|
|
||||||
LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
|
LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -30,5 +61,18 @@ LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
warning: type `PrivTy` is more private than the item `PubAlias2`
|
||||||
|
|
|
||||||
|
note: type alias `PubAlias2` is reachable at visibility `pub`
|
||||||
|
--> $DIR/private-in-public.rs:18:1
|
||||||
|
|
|
||||||
|
LL | pub type PubAlias2 = PubTy::PubAssocTy<PrivTy>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but type `PrivTy` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/private-in-public.rs:28:1
|
||||||
|
|
|
||||||
|
LL | struct PrivTy;
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors; 3 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
#![feature(generic_const_exprs)]
|
#![feature(generic_const_exprs)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
#![warn(private_interfaces)]
|
||||||
|
|
||||||
|
// In this test both old and new private-in-public diagnostic were emitted.
|
||||||
|
// Old diagnostic will be deleted soon.
|
||||||
|
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
|
||||||
|
|
||||||
pub struct Const<const U: u8>;
|
pub struct Const<const U: u8>;
|
||||||
|
|
||||||
pub trait Trait {
|
pub trait Trait {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
|
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
|
||||||
--> $DIR/eval-privacy.rs:16:5
|
--> $DIR/eval-privacy.rs:22:5
|
||||||
|
|
|
|
||||||
LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||||
| ^^^^^^^^^^^^ can't leak private type
|
| ^^^^^^^^^^^^ can't leak private type
|
||||||
|
@ -7,6 +7,24 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||||
LL | const fn my_const_fn(val: u8) -> u8 {
|
LL | const fn my_const_fn(val: u8) -> u8 {
|
||||||
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
|
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
|
||||||
|
|
||||||
error: aborting due to previous error
|
warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
|
||||||
|
|
|
||||||
|
note: associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
|
||||||
|
--> $DIR/eval-privacy.rs:22:5
|
||||||
|
|
|
||||||
|
LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/eval-privacy.rs:29:1
|
||||||
|
|
|
||||||
|
LL | const fn my_const_fn(val: u8) -> u8 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/eval-privacy.rs:5:9
|
||||||
|
|
|
||||||
|
LL | #![warn(private_interfaces)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0446`.
|
For more information about this error, try `rustc --explain E0446`.
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
#[warn(private_bounds)]
|
||||||
|
#[warn(private_interfaces)]
|
||||||
|
|
||||||
|
// In this test both old and new private-in-public diagnostic were emitted.
|
||||||
|
// Old diagnostic will be deleted soon.
|
||||||
|
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
|
||||||
|
|
||||||
trait Foo {
|
trait Foo {
|
||||||
fn dummy(&self) { }
|
fn dummy(&self) { }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0445]: private trait `Foo` in public interface
|
error[E0445]: private trait `Foo` in public interface
|
||||||
--> $DIR/E0445.rs:5:1
|
--> $DIR/E0445.rs:12:1
|
||||||
|
|
|
|
||||||
LL | trait Foo {
|
LL | trait Foo {
|
||||||
| --------- `Foo` declared as private
|
| --------- `Foo` declared as private
|
||||||
|
@ -7,8 +7,26 @@ LL | trait Foo {
|
||||||
LL | pub trait Bar : Foo {}
|
LL | pub trait Bar : Foo {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
| ^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
||||||
|
|
||||||
|
warning: trait `Foo` is more private than the item `Bar`
|
||||||
|
|
|
||||||
|
note: trait `Bar` is reachable at visibility `pub`
|
||||||
|
--> $DIR/E0445.rs:12:1
|
||||||
|
|
|
||||||
|
LL | pub trait Bar : Foo {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but trait `Foo` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/E0445.rs:8:1
|
||||||
|
|
|
||||||
|
LL | trait Foo {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/E0445.rs:1:8
|
||||||
|
|
|
||||||
|
LL | #[warn(private_bounds)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0445]: private trait `Foo` in public interface
|
error[E0445]: private trait `Foo` in public interface
|
||||||
--> $DIR/E0445.rs:7:1
|
--> $DIR/E0445.rs:14:1
|
||||||
|
|
|
|
||||||
LL | trait Foo {
|
LL | trait Foo {
|
||||||
| --------- `Foo` declared as private
|
| --------- `Foo` declared as private
|
||||||
|
@ -16,8 +34,21 @@ LL | trait Foo {
|
||||||
LL | pub struct Bar2<T: Foo>(pub T);
|
LL | pub struct Bar2<T: Foo>(pub T);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
| ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
||||||
|
|
||||||
|
warning: trait `Foo` is more private than the item `Bar2`
|
||||||
|
|
|
||||||
|
note: struct `Bar2` is reachable at visibility `pub`
|
||||||
|
--> $DIR/E0445.rs:14:1
|
||||||
|
|
|
||||||
|
LL | pub struct Bar2<T: Foo>(pub T);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but trait `Foo` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/E0445.rs:8:1
|
||||||
|
|
|
||||||
|
LL | trait Foo {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0445]: private trait `Foo` in public interface
|
error[E0445]: private trait `Foo` in public interface
|
||||||
--> $DIR/E0445.rs:9:1
|
--> $DIR/E0445.rs:16:1
|
||||||
|
|
|
|
||||||
LL | trait Foo {
|
LL | trait Foo {
|
||||||
| --------- `Foo` declared as private
|
| --------- `Foo` declared as private
|
||||||
|
@ -25,6 +56,19 @@ LL | trait Foo {
|
||||||
LL | pub fn foo<T: Foo> (t: T) {}
|
LL | pub fn foo<T: Foo> (t: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak private trait
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
warning: trait `Foo` is more private than the item `foo`
|
||||||
|
|
|
||||||
|
note: function `foo` is reachable at visibility `pub`
|
||||||
|
--> $DIR/E0445.rs:16:1
|
||||||
|
|
|
||||||
|
LL | pub fn foo<T: Foo> (t: T) {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but trait `Foo` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/E0445.rs:8:1
|
||||||
|
|
|
||||||
|
LL | trait Foo {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors; 3 warnings emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0445`.
|
For more information about this error, try `rustc --explain E0445`.
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
#![warn(private_bounds)]
|
||||||
|
|
||||||
|
// In this test both old and new private-in-public diagnostic were emitted.
|
||||||
|
// Old diagnostic will be deleted soon.
|
||||||
|
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
|
|
||||||
|
|
|
@ -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:7:1
|
--> $DIR/issue-18389.rs:13: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
|
||||||
|
@ -11,6 +11,28 @@ LL | | <Self as Public>::R
|
||||||
LL | | > {
|
LL | | > {
|
||||||
| |_^ can't leak private trait
|
| |_^ can't leak private trait
|
||||||
|
|
||||||
error: aborting due to previous error
|
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`
|
||||||
|
--> $DIR/issue-18389.rs:13:1
|
||||||
|
|
|
||||||
|
LL | / pub trait Public: Private<
|
||||||
|
LL | |
|
||||||
|
LL | | <Self as Public>::P,
|
||||||
|
LL | | <Self as Public>::R
|
||||||
|
LL | | > {
|
||||||
|
| |_^
|
||||||
|
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
|
||||||
|
|
|
||||||
|
LL | trait Private<P, R> {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-18389.rs:1:9
|
||||||
|
|
|
||||||
|
LL | #![warn(private_bounds)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to previous error; 1 warning emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0445`.
|
For more information about this error, try `rustc --explain E0445`.
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
#![feature(auto_traits)]
|
#![feature(auto_traits)]
|
||||||
#![feature(negative_impls)]
|
#![feature(negative_impls)]
|
||||||
|
|
||||||
|
#![deny(private_interfaces)]
|
||||||
|
|
||||||
|
// In this test both old and new private-in-public diagnostic were emitted.
|
||||||
|
// Old diagnostic will be deleted soon.
|
||||||
|
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
|
||||||
|
|
||||||
pub trait PubPrincipal {}
|
pub trait PubPrincipal {}
|
||||||
auto trait PrivNonPrincipal {}
|
auto trait PrivNonPrincipal {}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: private trait `PrivNonPrincipal` in public interface (error E0445)
|
warning: private trait `PrivNonPrincipal` in public interface (error E0445)
|
||||||
--> $DIR/private-in-public-non-principal.rs:7:1
|
--> $DIR/private-in-public-non-principal.rs:13:1
|
||||||
|
|
|
|
||||||
LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
|
LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -8,17 +8,35 @@ LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal>
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
= note: `#[warn(private_in_public)]` on by default
|
= note: `#[warn(private_in_public)]` on by default
|
||||||
|
|
||||||
|
error: trait `PrivNonPrincipal` is more private than the item `leak_dyn_nonprincipal`
|
||||||
|
|
|
||||||
|
note: function `leak_dyn_nonprincipal` is reachable at visibility `pub`
|
||||||
|
--> $DIR/private-in-public-non-principal.rs:13:1
|
||||||
|
|
|
||||||
|
LL | pub fn leak_dyn_nonprincipal() -> Box<dyn PubPrincipal + PrivNonPrincipal> { loop {} }
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but trait `PrivNonPrincipal` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/private-in-public-non-principal.rs:11:1
|
||||||
|
|
|
||||||
|
LL | auto trait PrivNonPrincipal {}
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/private-in-public-non-principal.rs:4:9
|
||||||
|
|
|
||||||
|
LL | #![deny(private_interfaces)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: missing documentation for an associated function
|
error: missing documentation for an associated function
|
||||||
--> $DIR/private-in-public-non-principal.rs:14:9
|
--> $DIR/private-in-public-non-principal.rs:20:9
|
||||||
|
|
|
|
||||||
LL | pub fn check_doc_lint() {}
|
LL | pub fn check_doc_lint() {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: the lint level is defined here
|
note: the lint level is defined here
|
||||||
--> $DIR/private-in-public-non-principal.rs:11:8
|
--> $DIR/private-in-public-non-principal.rs:17:8
|
||||||
|
|
|
|
||||||
LL | #[deny(missing_docs)]
|
LL | #[deny(missing_docs)]
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to previous error; 1 warning emitted
|
error: aborting due to 2 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,24 @@ trait TyParam {
|
||||||
fn ty_param_secret(&self);
|
fn ty_param_secret(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait Ref {
|
||||||
|
fn ref_secret(self);
|
||||||
|
}
|
||||||
|
|
||||||
mod m {
|
mod m {
|
||||||
struct Priv;
|
struct Priv;
|
||||||
|
|
||||||
impl ::Arr0 for [Priv; 0] { fn arr0_secret(&self) {} }
|
impl ::Arr0 for [Priv; 0] { fn arr0_secret(&self) {} }
|
||||||
impl ::TyParam for Option<Priv> { fn ty_param_secret(&self) {} }
|
impl ::TyParam for Option<Priv> { fn ty_param_secret(&self) {} }
|
||||||
|
impl<'a> ::Ref for &'a Priv { fn ref_secret(self) {} }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn anyref<'a, T>() -> &'a T { panic!() }
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
[].arr0_secret(); //~ ERROR type `Priv` is private
|
[].arr0_secret(); //~ ERROR type `Priv` is private
|
||||||
None.ty_param_secret(); //~ ERROR type `Priv` is private
|
None.ty_param_secret(); //~ ERROR type `Priv` is private
|
||||||
|
Ref::ref_secret(anyref());
|
||||||
|
//~^ ERROR type `Priv` is private
|
||||||
|
//~| ERROR type `Priv` is private
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,26 @@
|
||||||
error: type `Priv` is private
|
error: type `Priv` is private
|
||||||
--> $DIR/private-inferred-type-1.rs:16:5
|
--> $DIR/private-inferred-type-1.rs:23:5
|
||||||
|
|
|
|
||||||
LL | [].arr0_secret();
|
LL | [].arr0_secret();
|
||||||
| ^^^^^^^^^^^^^^^^ private type
|
| ^^^^^^^^^^^^^^^^ private type
|
||||||
|
|
||||||
error: type `Priv` is private
|
error: type `Priv` is private
|
||||||
--> $DIR/private-inferred-type-1.rs:17:5
|
--> $DIR/private-inferred-type-1.rs:24:5
|
||||||
|
|
|
|
||||||
LL | None.ty_param_secret();
|
LL | None.ty_param_secret();
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ private type
|
| ^^^^^^^^^^^^^^^^^^^^^^ private type
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: type `Priv` is private
|
||||||
|
--> $DIR/private-inferred-type-1.rs:25:5
|
||||||
|
|
|
||||||
|
LL | Ref::ref_secret(anyref());
|
||||||
|
| ^^^^^^^^^^^^^^^ private type
|
||||||
|
|
||||||
|
error: type `Priv` is private
|
||||||
|
--> $DIR/private-inferred-type-1.rs:25:21
|
||||||
|
|
|
||||||
|
LL | Ref::ref_secret(anyref());
|
||||||
|
| ^^^^^^^^ private type
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
30
tests/ui/privacy/unnameable_types.rs
Normal file
30
tests/ui/privacy/unnameable_types.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#![allow(unused)]
|
||||||
|
#![allow(private_in_public)]
|
||||||
|
#![deny(unnameable_types)]
|
||||||
|
|
||||||
|
mod m {
|
||||||
|
pub struct PubStruct(pub i32); //~ ERROR struct `PubStruct` is reachable but cannot be named
|
||||||
|
|
||||||
|
pub enum PubE { //~ ERROR enum `PubE` is reachable but cannot be named
|
||||||
|
V(i32),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PubTr { //~ ERROR trait `PubTr` is reachable but cannot be named
|
||||||
|
const C : i32 = 0;
|
||||||
|
type Alias; //~ ERROR associated type `PubTr::Alias` is reachable but cannot be named
|
||||||
|
fn f() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PubTr for PubStruct {
|
||||||
|
type Alias = i32; //~ ERROR associated type `<PubStruct as PubTr>::Alias` is reachable but cannot be named
|
||||||
|
fn f() {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Voldemort<T> {}
|
||||||
|
|
||||||
|
impl Voldemort<m::PubStruct> for i32 {}
|
||||||
|
impl Voldemort<m::PubE> for i32 {}
|
||||||
|
impl<T> Voldemort<T> for u32 where T: m::PubTr {}
|
||||||
|
|
||||||
|
fn main() {}
|
38
tests/ui/privacy/unnameable_types.stderr
Normal file
38
tests/ui/privacy/unnameable_types.stderr
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
error: struct `PubStruct` is reachable but cannot be named
|
||||||
|
--> $DIR/unnameable_types.rs:6:5
|
||||||
|
|
|
||||||
|
LL | pub struct PubStruct(pub i32);
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
|
||||||
|
|
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/unnameable_types.rs:3:9
|
||||||
|
|
|
||||||
|
LL | #![deny(unnameable_types)]
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: enum `PubE` is reachable but cannot be named
|
||||||
|
--> $DIR/unnameable_types.rs:8:5
|
||||||
|
|
|
||||||
|
LL | pub enum PubE {
|
||||||
|
| ^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
|
||||||
|
|
||||||
|
error: trait `PubTr` is reachable but cannot be named
|
||||||
|
--> $DIR/unnameable_types.rs:12:5
|
||||||
|
|
|
||||||
|
LL | pub trait PubTr {
|
||||||
|
| ^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
|
||||||
|
|
||||||
|
error: associated type `PubTr::Alias` is reachable but cannot be named
|
||||||
|
--> $DIR/unnameable_types.rs:14:9
|
||||||
|
|
|
||||||
|
LL | type Alias;
|
||||||
|
| ^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
|
||||||
|
|
||||||
|
error: associated type `<PubStruct as PubTr>::Alias` is reachable but cannot be named
|
||||||
|
--> $DIR/unnameable_types.rs:19:9
|
||||||
|
|
|
||||||
|
LL | type Alias = i32;
|
||||||
|
| ^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
|
@ -5,6 +5,12 @@
|
||||||
#![feature(generic_const_exprs)]
|
#![feature(generic_const_exprs)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
#![warn(private_bounds)]
|
||||||
|
#![warn(private_interfaces)]
|
||||||
|
|
||||||
|
// In this test both old and new private-in-public diagnostic were emitted.
|
||||||
|
// Old diagnostic will be deleted soon.
|
||||||
|
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
|
||||||
|
|
||||||
struct PrivTy;
|
struct PrivTy;
|
||||||
trait PrivTr {}
|
trait PrivTr {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: private type `PrivTy` in public interface (error E0446)
|
warning: private type `PrivTy` in public interface (error E0446)
|
||||||
--> $DIR/where-priv-type.rs:19:1
|
--> $DIR/where-priv-type.rs:25:1
|
||||||
|
|
|
|
||||||
LL | pub struct S
|
LL | pub struct S
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
@ -8,8 +8,26 @@ LL | pub struct S
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
= note: `#[warn(private_in_public)]` on by default
|
= note: `#[warn(private_in_public)]` on by default
|
||||||
|
|
||||||
|
warning: type `PrivTy` is more private than the item `S`
|
||||||
|
|
|
||||||
|
note: struct `S` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-priv-type.rs:25:1
|
||||||
|
|
|
||||||
|
LL | pub struct S
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
note: but type `PrivTy` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-priv-type.rs:15:1
|
||||||
|
|
|
||||||
|
LL | struct PrivTy;
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/where-priv-type.rs:8:9
|
||||||
|
|
|
||||||
|
LL | #![warn(private_bounds)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: private type `PrivTy` in public interface (error E0446)
|
warning: private type `PrivTy` in public interface (error E0446)
|
||||||
--> $DIR/where-priv-type.rs:27:1
|
--> $DIR/where-priv-type.rs:33:1
|
||||||
|
|
|
|
||||||
LL | pub enum E
|
LL | pub enum E
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -17,8 +35,21 @@ LL | pub enum E
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
|
|
||||||
|
warning: type `PrivTy` is more private than the item `E`
|
||||||
|
|
|
||||||
|
note: enum `E` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-priv-type.rs:33:1
|
||||||
|
|
|
||||||
|
LL | pub enum E
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
note: but type `PrivTy` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-priv-type.rs:15:1
|
||||||
|
|
|
||||||
|
LL | struct PrivTy;
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: private type `PrivTy` in public interface (error E0446)
|
warning: private type `PrivTy` in public interface (error E0446)
|
||||||
--> $DIR/where-priv-type.rs:35:1
|
--> $DIR/where-priv-type.rs:41:1
|
||||||
|
|
|
|
||||||
LL | / pub fn f()
|
LL | / pub fn f()
|
||||||
LL | |
|
LL | |
|
||||||
|
@ -30,8 +61,25 @@ LL | | PrivTy:
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
|
|
||||||
|
warning: type `PrivTy` is more private than the item `f`
|
||||||
|
|
|
||||||
|
note: function `f` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-priv-type.rs:41:1
|
||||||
|
|
|
||||||
|
LL | / pub fn f()
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | where
|
||||||
|
LL | | PrivTy:
|
||||||
|
| |___________^
|
||||||
|
note: but type `PrivTy` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-priv-type.rs:15:1
|
||||||
|
|
|
||||||
|
LL | struct PrivTy;
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0446]: private type `PrivTy` in public interface
|
error[E0446]: private type `PrivTy` in public interface
|
||||||
--> $DIR/where-priv-type.rs:43:1
|
--> $DIR/where-priv-type.rs:49:1
|
||||||
|
|
|
|
||||||
LL | struct PrivTy;
|
LL | struct PrivTy;
|
||||||
| ------------- `PrivTy` declared as private
|
| ------------- `PrivTy` declared as private
|
||||||
|
@ -39,8 +87,21 @@ LL | struct PrivTy;
|
||||||
LL | impl S
|
LL | impl S
|
||||||
| ^^^^^^ can't leak private type
|
| ^^^^^^ can't leak private type
|
||||||
|
|
||||||
|
warning: type `PrivTy` is more private than the item `S`
|
||||||
|
|
|
||||||
|
note: implementation `S` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-priv-type.rs:49:1
|
||||||
|
|
|
||||||
|
LL | impl S
|
||||||
|
| ^^^^^^
|
||||||
|
note: but type `PrivTy` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-priv-type.rs:15:1
|
||||||
|
|
|
||||||
|
LL | struct PrivTy;
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: private type `PrivTy` in public interface (error E0446)
|
warning: private type `PrivTy` in public interface (error E0446)
|
||||||
--> $DIR/where-priv-type.rs:48:5
|
--> $DIR/where-priv-type.rs:54:5
|
||||||
|
|
|
|
||||||
LL | / pub fn f()
|
LL | / pub fn f()
|
||||||
LL | |
|
LL | |
|
||||||
|
@ -52,8 +113,25 @@ LL | | PrivTy:
|
||||||
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
|
||||||
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
= note: for more information, see issue #34537 <https://github.com/rust-lang/rust/issues/34537>
|
||||||
|
|
||||||
|
warning: type `PrivTy` is more private than the item `S::f`
|
||||||
|
|
|
||||||
|
note: associated function `S::f` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-priv-type.rs:54:5
|
||||||
|
|
|
||||||
|
LL | / pub fn f()
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | where
|
||||||
|
LL | | PrivTy:
|
||||||
|
| |_______________^
|
||||||
|
note: but type `PrivTy` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-priv-type.rs:15:1
|
||||||
|
|
|
||||||
|
LL | struct PrivTy;
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
|
error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface
|
||||||
--> $DIR/where-priv-type.rs:80:5
|
--> $DIR/where-priv-type.rs:86:5
|
||||||
|
|
|
|
||||||
LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||||
| ^^^^^^^^^^^^ can't leak private type
|
| ^^^^^^^^^^^^ can't leak private type
|
||||||
|
@ -61,6 +139,24 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||||
LL | const fn my_const_fn(val: u8) -> u8 {
|
LL | const fn my_const_fn(val: u8) -> u8 {
|
||||||
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
|
| ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private
|
||||||
|
|
||||||
error: aborting due to 2 previous errors; 4 warnings emitted
|
warning: type `fn(u8) -> u8 {my_const_fn}` is more private than the item `<Const<U> as Trait>::AssocTy`
|
||||||
|
|
|
||||||
|
note: associated type `<Const<U> as Trait>::AssocTy` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-priv-type.rs:86:5
|
||||||
|
|
|
||||||
|
LL | type AssocTy = Const<{ my_const_fn(U) }>;
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
note: but type `fn(u8) -> u8 {my_const_fn}` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-priv-type.rs:93:1
|
||||||
|
|
|
||||||
|
LL | const fn my_const_fn(val: u8) -> u8 {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/where-priv-type.rs:9:9
|
||||||
|
|
|
||||||
|
LL | #![warn(private_interfaces)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors; 10 warnings emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0446`.
|
For more information about this error, try `rustc --explain E0446`.
|
||||||
|
|
|
@ -4,6 +4,11 @@
|
||||||
#![feature(generic_const_exprs)]
|
#![feature(generic_const_exprs)]
|
||||||
#![allow(incomplete_features)]
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
#![warn(private_bounds)]
|
||||||
|
|
||||||
|
// In this test both old and new private-in-public diagnostic were emitted.
|
||||||
|
// Old diagnostic will be deleted soon.
|
||||||
|
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
|
||||||
|
|
||||||
struct PrivTy;
|
struct PrivTy;
|
||||||
trait PrivTr {}
|
trait PrivTr {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error[E0445]: private trait `PrivTr` in public interface
|
error[E0445]: private trait `PrivTr` in public interface
|
||||||
--> $DIR/where-pub-type-impls-priv-trait.rs:19:1
|
--> $DIR/where-pub-type-impls-priv-trait.rs:24:1
|
||||||
|
|
|
|
||||||
LL | trait PrivTr {}
|
LL | trait PrivTr {}
|
||||||
| ------------ `PrivTr` declared as private
|
| ------------ `PrivTr` declared as private
|
||||||
|
@ -7,8 +7,26 @@ LL | trait PrivTr {}
|
||||||
LL | pub struct S
|
LL | pub struct S
|
||||||
| ^^^^^^^^^^^^ can't leak private trait
|
| ^^^^^^^^^^^^ can't leak private trait
|
||||||
|
|
||||||
|
warning: trait `PrivTr` is more private than the item `S`
|
||||||
|
|
|
||||||
|
note: struct `S` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:24:1
|
||||||
|
|
|
||||||
|
LL | pub struct S
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
note: but trait `PrivTr` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:14:1
|
||||||
|
|
|
||||||
|
LL | trait PrivTr {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:7:9
|
||||||
|
|
|
||||||
|
LL | #![warn(private_bounds)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0445]: private trait `PrivTr` in public interface
|
error[E0445]: private trait `PrivTr` in public interface
|
||||||
--> $DIR/where-pub-type-impls-priv-trait.rs:26:1
|
--> $DIR/where-pub-type-impls-priv-trait.rs:31:1
|
||||||
|
|
|
|
||||||
LL | trait PrivTr {}
|
LL | trait PrivTr {}
|
||||||
| ------------ `PrivTr` declared as private
|
| ------------ `PrivTr` declared as private
|
||||||
|
@ -16,8 +34,21 @@ LL | trait PrivTr {}
|
||||||
LL | pub enum E
|
LL | pub enum E
|
||||||
| ^^^^^^^^^^ can't leak private trait
|
| ^^^^^^^^^^ can't leak private trait
|
||||||
|
|
||||||
|
warning: trait `PrivTr` is more private than the item `E`
|
||||||
|
|
|
||||||
|
note: enum `E` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:31:1
|
||||||
|
|
|
||||||
|
LL | pub enum E
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
note: but trait `PrivTr` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:14:1
|
||||||
|
|
|
||||||
|
LL | trait PrivTr {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0445]: private trait `PrivTr` in public interface
|
error[E0445]: private trait `PrivTr` in public interface
|
||||||
--> $DIR/where-pub-type-impls-priv-trait.rs:33:1
|
--> $DIR/where-pub-type-impls-priv-trait.rs:38:1
|
||||||
|
|
|
|
||||||
LL | trait PrivTr {}
|
LL | trait PrivTr {}
|
||||||
| ------------ `PrivTr` declared as private
|
| ------------ `PrivTr` declared as private
|
||||||
|
@ -28,8 +59,24 @@ LL | | where
|
||||||
LL | | PubTy: PrivTr
|
LL | | PubTy: PrivTr
|
||||||
| |_________________^ can't leak private trait
|
| |_________________^ can't leak private trait
|
||||||
|
|
||||||
|
warning: trait `PrivTr` is more private than the item `f`
|
||||||
|
|
|
||||||
|
note: function `f` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:38:1
|
||||||
|
|
|
||||||
|
LL | / pub fn f()
|
||||||
|
LL | |
|
||||||
|
LL | | where
|
||||||
|
LL | | PubTy: PrivTr
|
||||||
|
| |_________________^
|
||||||
|
note: but trait `PrivTr` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:14:1
|
||||||
|
|
|
||||||
|
LL | trait PrivTr {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0445]: private trait `PrivTr` in public interface
|
error[E0445]: private trait `PrivTr` in public interface
|
||||||
--> $DIR/where-pub-type-impls-priv-trait.rs:40:1
|
--> $DIR/where-pub-type-impls-priv-trait.rs:45:1
|
||||||
|
|
|
|
||||||
LL | trait PrivTr {}
|
LL | trait PrivTr {}
|
||||||
| ------------ `PrivTr` declared as private
|
| ------------ `PrivTr` declared as private
|
||||||
|
@ -37,8 +84,21 @@ LL | trait PrivTr {}
|
||||||
LL | impl S
|
LL | impl S
|
||||||
| ^^^^^^ can't leak private trait
|
| ^^^^^^ can't leak private trait
|
||||||
|
|
||||||
|
warning: trait `PrivTr` is more private than the item `S`
|
||||||
|
|
|
||||||
|
note: implementation `S` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:45:1
|
||||||
|
|
|
||||||
|
LL | impl S
|
||||||
|
| ^^^^^^
|
||||||
|
note: but trait `PrivTr` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:14:1
|
||||||
|
|
|
||||||
|
LL | trait PrivTr {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
error[E0445]: private trait `PrivTr` in public interface
|
error[E0445]: private trait `PrivTr` in public interface
|
||||||
--> $DIR/where-pub-type-impls-priv-trait.rs:45:5
|
--> $DIR/where-pub-type-impls-priv-trait.rs:50:5
|
||||||
|
|
|
|
||||||
LL | trait PrivTr {}
|
LL | trait PrivTr {}
|
||||||
| ------------ `PrivTr` declared as private
|
| ------------ `PrivTr` declared as private
|
||||||
|
@ -49,6 +109,22 @@ LL | | where
|
||||||
LL | | PubTy: PrivTr
|
LL | | PubTy: PrivTr
|
||||||
| |_____________________^ can't leak private trait
|
| |_____________________^ can't leak private trait
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
warning: trait `PrivTr` is more private than the item `S::f`
|
||||||
|
|
|
||||||
|
note: associated function `S::f` is reachable at visibility `pub`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:50:5
|
||||||
|
|
|
||||||
|
LL | / pub fn f()
|
||||||
|
LL | |
|
||||||
|
LL | | where
|
||||||
|
LL | | PubTy: PrivTr
|
||||||
|
| |_____________________^
|
||||||
|
note: but trait `PrivTr` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/where-pub-type-impls-priv-trait.rs:14:1
|
||||||
|
|
|
||||||
|
LL | trait PrivTr {}
|
||||||
|
| ^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors; 5 warnings emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0445`.
|
For more information about this error, try `rustc --explain E0445`.
|
||||||
|
|
|
@ -1,15 +1,24 @@
|
||||||
#![allow(non_camel_case_types)] // genus is always capitalized
|
#![allow(non_camel_case_types)] // genus is always capitalized
|
||||||
|
#![warn(private_interfaces)]
|
||||||
|
//~^ NOTE the lint level is defined here
|
||||||
|
|
||||||
|
// In this test both old and new private-in-public diagnostic were emitted.
|
||||||
|
// Old diagnostic will be deleted soon.
|
||||||
|
// See https://rust-lang.github.io/rfcs/2145-type-privacy.html.
|
||||||
|
|
||||||
pub(crate) struct Snail;
|
pub(crate) struct Snail;
|
||||||
//~^ NOTE `Snail` declared as private
|
//~^ NOTE `Snail` declared as private
|
||||||
|
//~| NOTE but type `Snail` is only usable at visibility `pub(crate)`
|
||||||
|
|
||||||
mod sea {
|
mod sea {
|
||||||
pub(super) struct Turtle;
|
pub(super) struct Turtle;
|
||||||
//~^ NOTE `Turtle` declared as crate-private
|
//~^ NOTE `Turtle` declared as crate-private
|
||||||
|
//~| NOTE but type `Turtle` is only usable at visibility `pub(crate)`
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Tortoise;
|
struct Tortoise;
|
||||||
//~^ NOTE `Tortoise` declared as private
|
//~^ NOTE `Tortoise` declared as private
|
||||||
|
//~| NOTE but type `Tortoise` is only usable at visibility `pub(crate)`
|
||||||
|
|
||||||
pub struct Shell<T> {
|
pub struct Shell<T> {
|
||||||
pub(crate) creature: T,
|
pub(crate) creature: T,
|
||||||
|
@ -18,11 +27,14 @@ pub struct Shell<T> {
|
||||||
pub type Helix_pomatia = Shell<Snail>;
|
pub type Helix_pomatia = Shell<Snail>;
|
||||||
//~^ ERROR private type `Snail` in public interface
|
//~^ ERROR private type `Snail` in public interface
|
||||||
//~| NOTE can't leak private type
|
//~| NOTE can't leak private type
|
||||||
|
//~| NOTE type alias `Helix_pomatia` is reachable at visibility `pub`
|
||||||
pub type Dermochelys_coriacea = Shell<sea::Turtle>;
|
pub type Dermochelys_coriacea = Shell<sea::Turtle>;
|
||||||
//~^ ERROR crate-private type `Turtle` in public interface
|
//~^ ERROR crate-private type `Turtle` in public interface
|
||||||
//~| NOTE can't leak crate-private type
|
//~| NOTE can't leak crate-private type
|
||||||
|
//~| NOTE type alias `Dermochelys_coriacea` is reachable at visibility `pub`
|
||||||
pub type Testudo_graeca = Shell<Tortoise>;
|
pub type Testudo_graeca = Shell<Tortoise>;
|
||||||
//~^ ERROR private type `Tortoise` in public interface
|
//~^ ERROR private type `Tortoise` in public interface
|
||||||
//~| NOTE can't leak private type
|
//~| NOTE can't leak private type
|
||||||
|
//~| NOTE type alias `Testudo_graeca` is reachable at visibility `pub`
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -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:18:1
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:27:1
|
||||||
|
|
|
|
||||||
LL | pub(crate) struct Snail;
|
LL | pub(crate) struct Snail;
|
||||||
| ----------------------- `Snail` declared as private
|
| ----------------------- `Snail` declared as private
|
||||||
|
@ -7,8 +7,26 @@ LL | pub(crate) struct Snail;
|
||||||
LL | pub type Helix_pomatia = Shell<Snail>;
|
LL | pub type Helix_pomatia = Shell<Snail>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
|
| ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
|
||||||
|
|
||||||
|
warning: type `Snail` is more private than the item `Helix_pomatia`
|
||||||
|
|
|
||||||
|
note: type alias `Helix_pomatia` is reachable at visibility `pub`
|
||||||
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:27:1
|
||||||
|
|
|
||||||
|
LL | pub type Helix_pomatia = Shell<Snail>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but type `Snail` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:9:1
|
||||||
|
|
|
||||||
|
LL | pub(crate) struct Snail;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: the lint level is defined here
|
||||||
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:2:9
|
||||||
|
|
|
||||||
|
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:21:1
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:31:1
|
||||||
|
|
|
|
||||||
LL | pub(super) struct Turtle;
|
LL | pub(super) struct Turtle;
|
||||||
| ------------------------ `Turtle` declared as crate-private
|
| ------------------------ `Turtle` declared as crate-private
|
||||||
|
@ -16,8 +34,21 @@ LL | pub(super) struct Turtle;
|
||||||
LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
|
LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak crate-private type
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't leak crate-private type
|
||||||
|
|
||||||
|
warning: type `Turtle` is more private than the item `Dermochelys_coriacea`
|
||||||
|
|
|
||||||
|
note: type alias `Dermochelys_coriacea` is reachable at visibility `pub`
|
||||||
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:31:1
|
||||||
|
|
|
||||||
|
LL | pub type Dermochelys_coriacea = Shell<sea::Turtle>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but type `Turtle` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:14:5
|
||||||
|
|
|
||||||
|
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:24:1
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:35:1
|
||||||
|
|
|
|
||||||
LL | struct Tortoise;
|
LL | struct Tortoise;
|
||||||
| --------------- `Tortoise` declared as private
|
| --------------- `Tortoise` declared as private
|
||||||
|
@ -25,6 +56,19 @@ LL | struct Tortoise;
|
||||||
LL | pub type Testudo_graeca = Shell<Tortoise>;
|
LL | pub type Testudo_graeca = Shell<Tortoise>;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
|
| ^^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
warning: type `Tortoise` is more private than the item `Testudo_graeca`
|
||||||
|
|
|
||||||
|
note: type alias `Testudo_graeca` is reachable at visibility `pub`
|
||||||
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:35:1
|
||||||
|
|
|
||||||
|
LL | pub type Testudo_graeca = Shell<Tortoise>;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
note: but type `Tortoise` is only usable at visibility `pub(crate)`
|
||||||
|
--> $DIR/issue-33174-restricted-type-in-public-interface.rs:19:1
|
||||||
|
|
|
||||||
|
LL | struct Tortoise;
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors; 3 warnings emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0446`.
|
For more information about this error, try `rustc --explain E0446`.
|
||||||
|
|
Loading…
Add table
Reference in a new issue