@@ -14,8 +14,8 @@ use rustc_errors::struct_span_err;
1414use rustc_hir as hir;
1515use rustc_hir:: def:: { DefKind , Res } ;
1616use rustc_hir:: def_id:: { DefId , LocalDefId , LocalDefIdSet , CRATE_DEF_ID } ;
17- use rustc_hir:: intravisit:: { self , DeepVisitor , Visitor } ;
18- use rustc_hir:: { AssocItemKind , HirIdSet , Node , PatKind } ;
17+ use rustc_hir:: intravisit:: { self , Visitor } ;
18+ use rustc_hir:: { AssocItemKind , HirIdSet , ItemId , Node , PatKind } ;
1919use rustc_middle:: bug;
2020use rustc_middle:: hir:: nested_filter;
2121use rustc_middle:: middle:: privacy:: { AccessLevel , AccessLevels } ;
@@ -1802,12 +1802,12 @@ impl<'tcx> DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
18021802 }
18031803}
18041804
1805- struct PrivateItemsInPublicInterfacesVisitor < ' tcx > {
1805+ struct PrivateItemsInPublicInterfacesChecker < ' tcx > {
18061806 tcx : TyCtxt < ' tcx > ,
18071807 old_error_set_ancestry : LocalDefIdSet ,
18081808}
18091809
1810- impl < ' tcx > PrivateItemsInPublicInterfacesVisitor < ' tcx > {
1810+ impl < ' tcx > PrivateItemsInPublicInterfacesChecker < ' tcx > {
18111811 fn check (
18121812 & self ,
18131813 def_id : LocalDefId ,
@@ -1841,110 +1841,121 @@ impl<'tcx> PrivateItemsInPublicInterfacesVisitor<'tcx> {
18411841 check. ty ( ) ;
18421842 }
18431843 }
1844- }
1845-
1846- impl < ' tcx > Visitor < ' tcx > for PrivateItemsInPublicInterfacesVisitor < ' tcx > {
1847- type NestedFilter = nested_filter:: OnlyBodies ;
18481844
1849- fn nested_visit_map ( & mut self ) -> Self :: Map {
1850- self . tcx . hir ( )
1851- }
1852-
1853- fn visit_item ( & mut self , item : & ' tcx hir:: Item < ' tcx > ) {
1845+ pub fn check_item ( & mut self , id : ItemId ) {
18541846 let tcx = self . tcx ;
1855- let item_visibility = tcx. visibility ( item. def_id ) ;
1847+ let item_visibility = tcx. visibility ( id. def_id ) ;
1848+ let def_kind = tcx. def_kind ( id. def_id ) ;
1849+
1850+ if matches ! (
1851+ def_kind,
1852+ DefKind :: ExternCrate
1853+ | DefKind :: Mod
1854+ | DefKind :: Use
1855+ | DefKind :: Macro ( _)
1856+ | DefKind :: GlobalAsm
1857+ ) {
1858+ return ;
1859+ }
18561860
1857- match item. kind {
1858- // Crates are always public.
1859- hir:: ItemKind :: ExternCrate ( ..) => { }
1860- // All nested items are checked by `visit_item`.
1861- hir:: ItemKind :: Mod ( ..) => { }
1862- // Checked in resolve.
1863- hir:: ItemKind :: Use ( ..) => { }
1864- // No subitems.
1865- hir:: ItemKind :: Macro ( ..) | hir:: ItemKind :: GlobalAsm ( ..) => { }
1866- // Subitems of these items have inherited publicity.
1867- hir:: ItemKind :: Const ( ..)
1868- | hir:: ItemKind :: Static ( ..)
1869- | hir:: ItemKind :: Fn ( ..)
1870- | hir:: ItemKind :: TyAlias ( ..) => {
1871- self . check ( item. def_id , item_visibility) . generics ( ) . predicates ( ) . ty ( ) ;
1861+ match def_kind {
1862+ DefKind :: Const | DefKind :: Static ( _) | DefKind :: Fn | DefKind :: TyAlias => {
1863+ self . check ( id. def_id , item_visibility) . generics ( ) . predicates ( ) . ty ( ) ;
18721864 }
1873- hir :: ItemKind :: OpaqueTy ( .. ) => {
1865+ DefKind :: OpaqueTy => {
18741866 // `ty()` for opaque types is the underlying type,
18751867 // it's not a part of interface, so we skip it.
1876- self . check ( item . def_id , item_visibility) . generics ( ) . bounds ( ) ;
1868+ self . check ( id . def_id , item_visibility) . generics ( ) . bounds ( ) ;
18771869 }
1878- hir:: ItemKind :: Trait ( .., trait_item_refs) => {
1879- self . check ( item. def_id , item_visibility) . generics ( ) . predicates ( ) ;
1870+ DefKind :: Trait => {
1871+ let item = tcx. hir ( ) . item ( id) ;
1872+ if let hir:: ItemKind :: Trait ( .., trait_item_refs) = item. kind {
1873+ self . check ( item. def_id , item_visibility) . generics ( ) . predicates ( ) ;
18801874
1881- for trait_item_ref in trait_item_refs {
1882- self . check_assoc_item (
1883- trait_item_ref. id . def_id ,
1884- trait_item_ref. kind ,
1885- trait_item_ref. defaultness ,
1886- item_visibility,
1887- ) ;
1888-
1889- if let AssocItemKind :: Type = trait_item_ref. kind {
1890- self . check ( trait_item_ref. id . def_id , item_visibility) . bounds ( ) ;
1875+ for trait_item_ref in trait_item_refs {
1876+ self . check_assoc_item (
1877+ trait_item_ref. id . def_id ,
1878+ trait_item_ref. kind ,
1879+ trait_item_ref. defaultness ,
1880+ item_visibility,
1881+ ) ;
1882+
1883+ if let AssocItemKind :: Type = trait_item_ref. kind {
1884+ self . check ( trait_item_ref. id . def_id , item_visibility) . bounds ( ) ;
1885+ }
18911886 }
18921887 }
18931888 }
1894- hir :: ItemKind :: TraitAlias ( .. ) => {
1895- self . check ( item . def_id , item_visibility) . generics ( ) . predicates ( ) ;
1889+ DefKind :: TraitAlias => {
1890+ self . check ( id . def_id , item_visibility) . generics ( ) . predicates ( ) ;
18961891 }
1897- hir:: ItemKind :: Enum ( ref def, _) => {
1898- self . check ( item. def_id , item_visibility) . generics ( ) . predicates ( ) ;
1892+ DefKind :: Enum => {
1893+ let item = tcx. hir ( ) . item ( id) ;
1894+ if let hir:: ItemKind :: Enum ( ref def, _) = item. kind {
1895+ self . check ( item. def_id , item_visibility) . generics ( ) . predicates ( ) ;
18991896
1900- for variant in def. variants {
1901- for field in variant. data . fields ( ) {
1902- self . check ( self . tcx . hir ( ) . local_def_id ( field. hir_id ) , item_visibility) . ty ( ) ;
1897+ for variant in def. variants {
1898+ for field in variant. data . fields ( ) {
1899+ self . check ( self . tcx . hir ( ) . local_def_id ( field. hir_id ) , item_visibility)
1900+ . ty ( ) ;
1901+ }
19031902 }
19041903 }
19051904 }
19061905 // Subitems of foreign modules have their own publicity.
1907- hir:: ItemKind :: ForeignMod { items, .. } => {
1908- for foreign_item in items {
1909- let vis = tcx. visibility ( foreign_item. id . def_id ) ;
1910- self . check ( foreign_item. id . def_id , vis) . generics ( ) . predicates ( ) . ty ( ) ;
1906+ DefKind :: ForeignMod => {
1907+ let item = tcx. hir ( ) . item ( id) ;
1908+ if let hir:: ItemKind :: ForeignMod { items, .. } = item. kind {
1909+ for foreign_item in items {
1910+ let vis = tcx. visibility ( foreign_item. id . def_id ) ;
1911+ self . check ( foreign_item. id . def_id , vis) . generics ( ) . predicates ( ) . ty ( ) ;
1912+ }
19111913 }
19121914 }
19131915 // Subitems of structs and unions have their own publicity.
1914- hir:: ItemKind :: Struct ( ref struct_def, _) | hir:: ItemKind :: Union ( ref struct_def, _) => {
1915- self . check ( item. def_id , item_visibility) . generics ( ) . predicates ( ) ;
1916+ DefKind :: Struct | DefKind :: Union => {
1917+ let item = tcx. hir ( ) . item ( id) ;
1918+ if let hir:: ItemKind :: Struct ( ref struct_def, _)
1919+ | hir:: ItemKind :: Union ( ref struct_def, _) = item. kind
1920+ {
1921+ self . check ( item. def_id , item_visibility) . generics ( ) . predicates ( ) ;
19161922
1917- for field in struct_def. fields ( ) {
1918- let def_id = tcx. hir ( ) . local_def_id ( field. hir_id ) ;
1919- let field_visibility = tcx. visibility ( def_id) ;
1920- self . check ( def_id, min ( item_visibility, field_visibility, tcx) ) . ty ( ) ;
1923+ for field in struct_def. fields ( ) {
1924+ let def_id = tcx. hir ( ) . local_def_id ( field. hir_id ) ;
1925+ let field_visibility = tcx. visibility ( def_id) ;
1926+ self . check ( def_id, min ( item_visibility, field_visibility, tcx) ) . ty ( ) ;
1927+ }
19211928 }
19221929 }
19231930 // An inherent impl is public when its type is public
19241931 // Subitems of inherent impls have their own publicity.
19251932 // A trait impl is public when both its type and its trait are public
19261933 // Subitems of trait impls have inherited publicity.
1927- hir:: ItemKind :: Impl ( ref impl_) => {
1928- let impl_vis = ty:: Visibility :: of_impl ( item. def_id , tcx, & Default :: default ( ) ) ;
1929- // check that private components do not appear in the generics or predicates of inherent impls
1930- // this check is intentionally NOT performed for impls of traits, per #90586
1931- if impl_. of_trait . is_none ( ) {
1932- self . check ( item. def_id , impl_vis) . generics ( ) . predicates ( ) ;
1933- }
1934- for impl_item_ref in impl_. items {
1935- let impl_item_vis = if impl_. of_trait . is_none ( ) {
1936- min ( tcx. visibility ( impl_item_ref. id . def_id ) , impl_vis, tcx)
1937- } else {
1938- impl_vis
1939- } ;
1940- self . check_assoc_item (
1941- impl_item_ref. id . def_id ,
1942- impl_item_ref. kind ,
1943- impl_item_ref. defaultness ,
1944- impl_item_vis,
1945- ) ;
1934+ DefKind :: Impl => {
1935+ let item = tcx. hir ( ) . item ( id) ;
1936+ if let hir:: ItemKind :: Impl ( ref impl_) = item. kind {
1937+ let impl_vis = ty:: Visibility :: of_impl ( item. def_id , tcx, & Default :: default ( ) ) ;
1938+ // check that private components do not appear in the generics or predicates of inherent impls
1939+ // this check is intentionally NOT performed for impls of traits, per #90586
1940+ if impl_. of_trait . is_none ( ) {
1941+ self . check ( item. def_id , impl_vis) . generics ( ) . predicates ( ) ;
1942+ }
1943+ for impl_item_ref in impl_. items {
1944+ let impl_item_vis = if impl_. of_trait . is_none ( ) {
1945+ min ( tcx. visibility ( impl_item_ref. id . def_id ) , impl_vis, tcx)
1946+ } else {
1947+ impl_vis
1948+ } ;
1949+ self . check_assoc_item (
1950+ impl_item_ref. id . def_id ,
1951+ impl_item_ref. kind ,
1952+ impl_item_ref. defaultness ,
1953+ impl_item_vis,
1954+ ) ;
1955+ }
19461956 }
19471957 }
1958+ _ => { }
19481959 }
19491960 }
19501961}
@@ -2069,7 +2080,7 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
20692080 }
20702081
20712082 // Check for private types and traits in public interfaces.
2072- let mut visitor = PrivateItemsInPublicInterfacesVisitor {
2083+ let mut checker = PrivateItemsInPublicInterfacesChecker {
20732084 tcx,
20742085 // Only definition IDs are ever searched in `old_error_set_ancestry`,
20752086 // so we can filter away all non-definition IDs at this point.
@@ -2078,5 +2089,8 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
20782089 . filter_map ( |hir_id| tcx. hir ( ) . opt_local_def_id ( hir_id) )
20792090 . collect ( ) ,
20802091 } ;
2081- tcx. hir ( ) . visit_all_item_likes ( & mut DeepVisitor :: new ( & mut visitor) ) ;
2092+
2093+ for id in tcx. hir ( ) . items ( ) {
2094+ checker. check_item ( id) ;
2095+ }
20822096}
0 commit comments