@@ -22,7 +22,7 @@ use rustc_hir as hir;
22
22
use rustc_hir:: def:: { DefKind , Res } ;
23
23
use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId , CRATE_DEF_ID } ;
24
24
use rustc_hir:: intravisit:: { self , Visitor } ;
25
- use rustc_hir:: { AssocItemKind , ForeignItemKind , ItemId , Node , PatKind } ;
25
+ use rustc_hir:: { AssocItemKind , ForeignItemId , ItemId , Node , PatKind } ;
26
26
use rustc_middle:: bug;
27
27
use rustc_middle:: hir:: nested_filter;
28
28
use rustc_middle:: middle:: privacy:: { EffectiveVisibilities , EffectiveVisibility , Level } ;
@@ -1607,15 +1607,16 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
1607
1607
fn check_assoc_item (
1608
1608
& self ,
1609
1609
def_id : LocalDefId ,
1610
- assoc_item_kind : AssocItemKind ,
1610
+ def_kind : DefKind ,
1611
1611
vis : ty:: Visibility ,
1612
1612
effective_vis : Option < EffectiveVisibility > ,
1613
1613
) {
1614
1614
let mut check = self . check ( def_id, vis, effective_vis) ;
1615
1615
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" ) ,
1619
1620
} ;
1620
1621
1621
1622
check. in_assoc_ty = is_assoc_ty;
@@ -1629,7 +1630,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
1629
1630
self . effective_visibilities . effective_vis ( def_id) . copied ( )
1630
1631
}
1631
1632
1632
- pub fn check_item ( & mut self , id : ItemId ) {
1633
+ fn check_item ( & mut self , id : ItemId ) {
1633
1634
let tcx = self . tcx ;
1634
1635
let def_id = id. owner_id . def_id ;
1635
1636
let item_visibility = tcx. local_visibility ( def_id) ;
@@ -1649,164 +1650,116 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
1649
1650
self . check ( def_id, item_visibility, effective_vis) . generics ( ) . bounds ( ) ;
1650
1651
}
1651
1652
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) ;
1659
1654
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 ( ) ;
1667
1656
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 ( ) ;
1676
1666
}
1677
1667
}
1678
1668
}
1679
1669
DefKind :: TraitAlias => {
1680
1670
self . check ( def_id, item_visibility, effective_vis) . generics ( ) . predicates ( ) ;
1681
1671
}
1682
1672
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 ( ) ;
1711
1675
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 ( ) ;
1717
1679
}
1718
1680
}
1719
1681
// Subitems of structs and unions have their own publicity.
1720
1682
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 ( ) ;
1729
1685
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 ( ) ;
1741
1692
}
1742
1693
}
1694
+ // Subitems of foreign modules have their own publicity.
1695
+ DefKind :: ForeignMod => { }
1743
1696
// An inherent impl is public when its type is public
1744
1697
// Subitems of inherent impls have their own publicity.
1745
1698
// A trait impl is public when both its type and its trait are public
1746
1699
// 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 ( ) ) ;
1772
1702
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 ;
1779
1725
}
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
+ } ;
1790
1732
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
+ ) ;
1805
1745
}
1806
1746
}
1807
1747
_ => { }
1808
1748
}
1809
1749
}
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
+ }
1810
1763
}
1811
1764
1812
1765
pub fn provide ( providers : & mut Providers ) {
@@ -1937,7 +1890,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
1937
1890
// Check for private types in public interfaces.
1938
1891
let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities } ;
1939
1892
1940
- for id in tcx. hir ( ) . items ( ) {
1893
+ let crate_items = tcx. hir_crate_items ( ( ) ) ;
1894
+ for id in crate_items. items ( ) {
1941
1895
checker. check_item ( id) ;
1942
1896
}
1897
+ for id in crate_items. foreign_items ( ) {
1898
+ checker. check_foreign_item ( id) ;
1899
+ }
1943
1900
}
0 commit comments