@@ -22,7 +22,7 @@ use rustc_hir as hir;
2222use rustc_hir:: def:: { DefKind , Res } ;
2323use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId , CRATE_DEF_ID } ;
2424use rustc_hir:: intravisit:: { self , Visitor } ;
25- use rustc_hir:: { AssocItemKind , ForeignItemKind , ItemId , Node , PatKind } ;
25+ use rustc_hir:: { AssocItemKind , ForeignItemId , ItemId , Node , PatKind } ;
2626use rustc_middle:: bug;
2727use rustc_middle:: hir:: nested_filter;
2828use 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
18121765pub 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}
0 commit comments