Skip to content

Commit cba27a0

Browse files
committed
Auto merge of rust-lang#116316 - cjgillot:incr-privacy, r=<try>
Remove eval_always from check_private_in_public.
2 parents e3c631b + 1da8198 commit cba27a0

File tree

3 files changed

+129
-173
lines changed

3 files changed

+129
-173
lines changed

compiler/rustc_middle/src/query/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -1129,7 +1129,6 @@ rustc_queries! {
11291129
desc { "checking effective visibilities" }
11301130
}
11311131
query check_private_in_public(_: ()) -> () {
1132-
eval_always
11331132
desc { "checking for private elements in public interfaces" }
11341133
}
11351134

compiler/rustc_privacy/src/lib.rs

+93-136
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_hir as hir;
2222
use rustc_hir::def::{DefKind, Res};
2323
use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, CRATE_DEF_ID};
2424
use rustc_hir::intravisit::{self, Visitor};
25-
use rustc_hir::{AssocItemKind, ForeignItemKind, ItemId, Node, PatKind};
25+
use rustc_hir::{AssocItemKind, ForeignItemId, ItemId, Node, PatKind};
2626
use rustc_middle::bug;
2727
use rustc_middle::hir::nested_filter;
2828
use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
@@ -1607,15 +1607,16 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
16071607
fn check_assoc_item(
16081608
&self,
16091609
def_id: LocalDefId,
1610-
assoc_item_kind: AssocItemKind,
1610+
def_kind: DefKind,
16111611
vis: ty::Visibility,
16121612
effective_vis: Option<EffectiveVisibility>,
16131613
) {
16141614
let mut check = self.check(def_id, vis, effective_vis);
16151615

1616-
let (check_ty, is_assoc_ty) = match assoc_item_kind {
1617-
AssocItemKind::Const | AssocItemKind::Fn { .. } => (true, false),
1618-
AssocItemKind::Type => (self.tcx.defaultness(def_id).has_value(), true),
1616+
let (check_ty, is_assoc_ty) = match def_kind {
1617+
DefKind::AssocConst | DefKind::AssocFn => (true, false),
1618+
DefKind::AssocTy => (self.tcx.defaultness(def_id).has_value(), true),
1619+
_ => bug!("wrong def_kind for associated item"),
16191620
};
16201621

16211622
check.in_assoc_ty = is_assoc_ty;
@@ -1629,7 +1630,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
16291630
self.effective_visibilities.effective_vis(def_id).copied()
16301631
}
16311632

1632-
pub fn check_item(&mut self, id: ItemId) {
1633+
fn check_item(&mut self, id: ItemId) {
16331634
let tcx = self.tcx;
16341635
let def_id = id.owner_id.def_id;
16351636
let item_visibility = tcx.local_visibility(def_id);
@@ -1649,164 +1650,116 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
16491650
self.check(def_id, item_visibility, effective_vis).generics().bounds();
16501651
}
16511652
DefKind::Trait => {
1652-
let item = tcx.hir().item(id);
1653-
if let hir::ItemKind::Trait(.., trait_item_refs) = item.kind {
1654-
self.check_unnameable(item.owner_id.def_id, effective_vis);
1655-
1656-
self.check(item.owner_id.def_id, item_visibility, effective_vis)
1657-
.generics()
1658-
.predicates();
1653+
self.check_unnameable(def_id, effective_vis);
16591654

1660-
for trait_item_ref in trait_item_refs {
1661-
self.check_assoc_item(
1662-
trait_item_ref.id.owner_id.def_id,
1663-
trait_item_ref.kind,
1664-
item_visibility,
1665-
effective_vis,
1666-
);
1655+
self.check(def_id, item_visibility, effective_vis).generics().predicates();
16671656

1668-
if let AssocItemKind::Type = trait_item_ref.kind {
1669-
self.check(
1670-
trait_item_ref.id.owner_id.def_id,
1671-
item_visibility,
1672-
effective_vis,
1673-
)
1674-
.bounds();
1675-
}
1657+
for &assoc_id in tcx.associated_item_def_ids(def_id) {
1658+
if tcx.is_impl_trait_in_trait(assoc_id) {
1659+
continue;
1660+
}
1661+
let assoc_id = assoc_id.expect_local();
1662+
let def_kind = tcx.def_kind(assoc_id);
1663+
self.check_assoc_item(assoc_id, def_kind, item_visibility, effective_vis);
1664+
if let DefKind::AssocTy = def_kind {
1665+
self.check(assoc_id, item_visibility, effective_vis).bounds();
16761666
}
16771667
}
16781668
}
16791669
DefKind::TraitAlias => {
16801670
self.check(def_id, item_visibility, effective_vis).generics().predicates();
16811671
}
16821672
DefKind::Enum => {
1683-
let item = tcx.hir().item(id);
1684-
if let hir::ItemKind::Enum(ref def, _) = item.kind {
1685-
self.check_unnameable(item.owner_id.def_id, effective_vis);
1686-
1687-
self.check(item.owner_id.def_id, item_visibility, effective_vis)
1688-
.generics()
1689-
.predicates();
1690-
1691-
for variant in def.variants {
1692-
for field in variant.data.fields() {
1693-
self.check(field.def_id, item_visibility, effective_vis).ty();
1694-
}
1695-
}
1696-
}
1697-
}
1698-
// Subitems of foreign modules have their own publicity.
1699-
DefKind::ForeignMod => {
1700-
let item = tcx.hir().item(id);
1701-
if let hir::ItemKind::ForeignMod { items, .. } = item.kind {
1702-
for foreign_item in items {
1703-
let foreign_item = tcx.hir().foreign_item(foreign_item.id);
1704-
1705-
let ev = self.get(foreign_item.owner_id.def_id);
1706-
let vis = tcx.local_visibility(foreign_item.owner_id.def_id);
1707-
1708-
if let ForeignItemKind::Type = foreign_item.kind {
1709-
self.check_unnameable(foreign_item.owner_id.def_id, ev);
1710-
}
1673+
self.check_unnameable(def_id, effective_vis);
1674+
self.check(def_id, item_visibility, effective_vis).generics().predicates();
17111675

1712-
self.check(foreign_item.owner_id.def_id, vis, ev)
1713-
.generics()
1714-
.predicates()
1715-
.ty();
1716-
}
1676+
let adt = tcx.adt_def(id.owner_id);
1677+
for field in adt.all_fields() {
1678+
self.check(field.did.expect_local(), item_visibility, effective_vis).ty();
17171679
}
17181680
}
17191681
// Subitems of structs and unions have their own publicity.
17201682
DefKind::Struct | DefKind::Union => {
1721-
let item = tcx.hir().item(id);
1722-
if let hir::ItemKind::Struct(ref struct_def, _)
1723-
| hir::ItemKind::Union(ref struct_def, _) = item.kind
1724-
{
1725-
self.check_unnameable(item.owner_id.def_id, effective_vis);
1726-
self.check(item.owner_id.def_id, item_visibility, effective_vis)
1727-
.generics()
1728-
.predicates();
1683+
self.check_unnameable(def_id, effective_vis);
1684+
self.check(def_id, item_visibility, effective_vis).generics().predicates();
17291685

1730-
for field in struct_def.fields() {
1731-
let field_visibility = tcx.local_visibility(field.def_id);
1732-
let field_ev = self.get(field.def_id);
1733-
1734-
self.check(
1735-
field.def_id,
1736-
min(item_visibility, field_visibility, tcx),
1737-
field_ev,
1738-
)
1739-
.ty();
1740-
}
1686+
let adt = tcx.adt_def(id.owner_id);
1687+
for field in adt.all_fields() {
1688+
let visibility = min(item_visibility, field.vis.expect_local(), tcx);
1689+
let field_ev = self.get(field.did.expect_local());
1690+
1691+
self.check(field.did.expect_local(), visibility, field_ev).ty();
17411692
}
17421693
}
1694+
// Subitems of foreign modules have their own publicity.
1695+
DefKind::ForeignMod => {}
17431696
// An inherent impl is public when its type is public
17441697
// Subitems of inherent impls have their own publicity.
17451698
// A trait impl is public when both its type and its trait are public
17461699
// Subitems of trait impls have inherited publicity.
1747-
DefKind::Impl { .. } => {
1748-
let item = tcx.hir().item(id);
1749-
if let hir::ItemKind::Impl(ref impl_) = item.kind {
1750-
let impl_vis = ty::Visibility::of_impl::<false>(
1751-
item.owner_id.def_id,
1752-
tcx,
1753-
&Default::default(),
1754-
);
1755-
1756-
// We are using the non-shallow version here, unlike when building the
1757-
// effective visisibilities table to avoid large number of false positives.
1758-
// For example in
1759-
//
1760-
// impl From<Priv> for Pub {
1761-
// fn from(_: Priv) -> Pub {...}
1762-
// }
1763-
//
1764-
// lints shouldn't be emmited even if `from` effective visibility
1765-
// is larger than `Priv` nominal visibility and if `Priv` can leak
1766-
// in some scenarios due to type inference.
1767-
let impl_ev = EffectiveVisibility::of_impl::<false>(
1768-
item.owner_id.def_id,
1769-
tcx,
1770-
self.effective_visibilities,
1771-
);
1700+
DefKind::Impl { of_trait } => {
1701+
let impl_vis = ty::Visibility::of_impl::<false>(def_id, tcx, &Default::default());
17721702

1773-
// check that private components do not appear in the generics or predicates of inherent impls
1774-
// this check is intentionally NOT performed for impls of traits, per #90586
1775-
if impl_.of_trait.is_none() {
1776-
self.check(item.owner_id.def_id, impl_vis, Some(impl_ev))
1777-
.generics()
1778-
.predicates();
1703+
// We are using the non-shallow version here, unlike when building the
1704+
// effective visisibilities table to avoid large number of false positives.
1705+
// For example in
1706+
//
1707+
// impl From<Priv> for Pub {
1708+
// fn from(_: Priv) -> Pub {...}
1709+
// }
1710+
//
1711+
// lints shouldn't be emmited even if `from` effective visibility
1712+
// is larger than `Priv` nominal visibility and if `Priv` can leak
1713+
// in some scenarios due to type inference.
1714+
let impl_ev =
1715+
EffectiveVisibility::of_impl::<false>(def_id, tcx, self.effective_visibilities);
1716+
1717+
// check that private components do not appear in the generics or predicates of inherent impls
1718+
// this check is intentionally NOT performed for impls of traits, per #90586
1719+
if !of_trait {
1720+
self.check(def_id, impl_vis, Some(impl_ev)).generics().predicates();
1721+
}
1722+
for &assoc_id in tcx.associated_item_def_ids(def_id) {
1723+
if tcx.is_impl_trait_in_trait(assoc_id) {
1724+
continue;
17791725
}
1780-
for impl_item_ref in impl_.items {
1781-
let impl_item_vis = if impl_.of_trait.is_none() {
1782-
min(
1783-
tcx.local_visibility(impl_item_ref.id.owner_id.def_id),
1784-
impl_vis,
1785-
tcx,
1786-
)
1787-
} else {
1788-
impl_vis
1789-
};
1726+
let assoc_id = assoc_id.expect_local();
1727+
let impl_item_vis = if !of_trait {
1728+
min(tcx.local_visibility(assoc_id), impl_vis, tcx)
1729+
} else {
1730+
impl_vis
1731+
};
17901732

1791-
let impl_item_ev = if impl_.of_trait.is_none() {
1792-
self.get(impl_item_ref.id.owner_id.def_id)
1793-
.map(|ev| ev.min(impl_ev, self.tcx))
1794-
} else {
1795-
Some(impl_ev)
1796-
};
1797-
1798-
self.check_assoc_item(
1799-
impl_item_ref.id.owner_id.def_id,
1800-
impl_item_ref.kind,
1801-
impl_item_vis,
1802-
impl_item_ev,
1803-
);
1804-
}
1733+
let impl_item_ev = if !of_trait {
1734+
self.get(assoc_id).map(|ev| ev.min(impl_ev, self.tcx))
1735+
} else {
1736+
Some(impl_ev)
1737+
};
1738+
1739+
self.check_assoc_item(
1740+
assoc_id,
1741+
tcx.def_kind(assoc_id),
1742+
impl_item_vis,
1743+
impl_item_ev,
1744+
);
18051745
}
18061746
}
18071747
_ => {}
18081748
}
18091749
}
1750+
1751+
fn check_foreign_item(&mut self, id: ForeignItemId) {
1752+
let tcx = self.tcx;
1753+
let def_id = id.owner_id.def_id;
1754+
let item_visibility = tcx.local_visibility(def_id);
1755+
let effective_vis = self.get(def_id);
1756+
1757+
if let DefKind::ForeignTy = self.tcx.def_kind(def_id) {
1758+
self.check_unnameable(def_id, effective_vis);
1759+
}
1760+
1761+
self.check(def_id, item_visibility, effective_vis).generics().predicates().ty();
1762+
}
18101763
}
18111764

18121765
pub fn provide(providers: &mut Providers) {
@@ -1937,7 +1890,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
19371890
// Check for private types in public interfaces.
19381891
let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities };
19391892

1940-
for id in tcx.hir().items() {
1893+
let crate_items = tcx.hir_crate_items(());
1894+
for id in crate_items.items() {
19411895
checker.check_item(id);
19421896
}
1897+
for id in crate_items.foreign_items() {
1898+
checker.check_foreign_item(id);
1899+
}
19431900
}

tests/ui/privacy/private-in-public-warn.stderr

+36-36
Original file line numberDiff line numberDiff line change
@@ -84,42 +84,6 @@ note: but type `types::Priv` is only usable at visibility `pub(self)`
8484
LL | struct Priv;
8585
| ^^^^^^^^^^^
8686

87-
error: type `types::Priv` is more private than the item `types::ES`
88-
--> $DIR/private-in-public-warn.rs:27:9
89-
|
90-
LL | pub static ES: Priv;
91-
| ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)`
92-
|
93-
note: but type `types::Priv` is only usable at visibility `pub(self)`
94-
--> $DIR/private-in-public-warn.rs:9:5
95-
|
96-
LL | struct Priv;
97-
| ^^^^^^^^^^^
98-
99-
error: type `types::Priv` is more private than the item `types::ef1`
100-
--> $DIR/private-in-public-warn.rs:28:9
101-
|
102-
LL | pub fn ef1(arg: Priv);
103-
| ^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)`
104-
|
105-
note: but type `types::Priv` is only usable at visibility `pub(self)`
106-
--> $DIR/private-in-public-warn.rs:9:5
107-
|
108-
LL | struct Priv;
109-
| ^^^^^^^^^^^
110-
111-
error: type `types::Priv` is more private than the item `types::ef2`
112-
--> $DIR/private-in-public-warn.rs:29:9
113-
|
114-
LL | pub fn ef2() -> Priv;
115-
| ^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)`
116-
|
117-
note: but type `types::Priv` is only usable at visibility `pub(self)`
118-
--> $DIR/private-in-public-warn.rs:9:5
119-
|
120-
LL | struct Priv;
121-
| ^^^^^^^^^^^
122-
12387
error[E0446]: private type `types::Priv` in public interface
12488
--> $DIR/private-in-public-warn.rs:32:9
12589
|
@@ -395,6 +359,42 @@ note: but type `Priv2` is only usable at visibility `pub(self)`
395359
LL | struct Priv2;
396360
| ^^^^^^^^^^^^
397361

362+
error: type `types::Priv` is more private than the item `types::ES`
363+
--> $DIR/private-in-public-warn.rs:27:9
364+
|
365+
LL | pub static ES: Priv;
366+
| ^^^^^^^^^^^^^^^^^^^ static `types::ES` is reachable at visibility `pub(crate)`
367+
|
368+
note: but type `types::Priv` is only usable at visibility `pub(self)`
369+
--> $DIR/private-in-public-warn.rs:9:5
370+
|
371+
LL | struct Priv;
372+
| ^^^^^^^^^^^
373+
374+
error: type `types::Priv` is more private than the item `types::ef1`
375+
--> $DIR/private-in-public-warn.rs:28:9
376+
|
377+
LL | pub fn ef1(arg: Priv);
378+
| ^^^^^^^^^^^^^^^^^^^^^ function `types::ef1` is reachable at visibility `pub(crate)`
379+
|
380+
note: but type `types::Priv` is only usable at visibility `pub(self)`
381+
--> $DIR/private-in-public-warn.rs:9:5
382+
|
383+
LL | struct Priv;
384+
| ^^^^^^^^^^^
385+
386+
error: type `types::Priv` is more private than the item `types::ef2`
387+
--> $DIR/private-in-public-warn.rs:29:9
388+
|
389+
LL | pub fn ef2() -> Priv;
390+
| ^^^^^^^^^^^^^^^^^^^^ function `types::ef2` is reachable at visibility `pub(crate)`
391+
|
392+
note: but type `types::Priv` is only usable at visibility `pub(self)`
393+
--> $DIR/private-in-public-warn.rs:9:5
394+
|
395+
LL | struct Priv;
396+
| ^^^^^^^^^^^
397+
398398
warning: bounds on generic parameters are not enforced in type aliases
399399
--> $DIR/private-in-public-warn.rs:41:23
400400
|

0 commit comments

Comments
 (0)