@@ -26,7 +26,7 @@ use rustc_errors::{MultiSpan, listify};
2626use rustc_hir:: def:: { DefKind , Res } ;
2727use rustc_hir:: def_id:: { CRATE_DEF_ID , DefId , LocalDefId , LocalModDefId } ;
2828use rustc_hir:: intravisit:: { self , InferKind , Visitor } ;
29- use rustc_hir:: { AmbigArg , ForeignItemKind , ItemId , ItemKind , PatKind } ;
29+ use rustc_hir:: { AmbigArg , ForeignItemId , ItemId , PatKind } ;
3030use rustc_middle:: middle:: privacy:: { EffectiveVisibilities , EffectiveVisibility , Level } ;
3131use rustc_middle:: query:: Providers ;
3232use rustc_middle:: ty:: print:: PrintTraitRefExt as _;
@@ -599,18 +599,13 @@ impl<'tcx> EmbargoVisitor<'tcx> {
599599
600600 DefKind :: Struct | DefKind :: Union => {
601601 // While structs and unions have type privacy, their fields do not.
602- let item = self . tcx . hir_expect_item ( def_id) ;
603- if let hir:: ItemKind :: Struct ( _, _, ref struct_def)
604- | hir:: ItemKind :: Union ( _, _, ref struct_def) = item. kind
605- {
606- for field in struct_def. fields ( ) {
607- let field_vis = self . tcx . local_visibility ( field. def_id ) ;
608- if field_vis. is_accessible_from ( module, self . tcx ) {
609- self . reach ( field. def_id , macro_ev) . ty ( ) ;
610- }
602+ let struct_def = self . tcx . adt_def ( def_id) ;
603+ for field in struct_def. non_enum_variant ( ) . fields . iter ( ) {
604+ let def_id = field. did . expect_local ( ) ;
605+ let field_vis = self . tcx . local_visibility ( def_id) ;
606+ if field_vis. is_accessible_from ( module, self . tcx ) {
607+ self . reach ( def_id, macro_ev) . ty ( ) ;
611608 }
612- } else {
613- bug ! ( "item {:?} with DefKind {:?}" , item, def_kind) ;
614609 }
615610 }
616611
@@ -1640,66 +1635,29 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
16401635 self . check ( def_id, item_visibility, effective_vis) . generics ( ) . predicates ( ) ;
16411636 }
16421637 DefKind :: Enum => {
1643- let item = tcx. hir_item ( id) ;
1644- if let hir:: ItemKind :: Enum ( _, _, ref def) = item. kind {
1645- self . check_unnameable ( item. owner_id . def_id , effective_vis) ;
1646-
1647- self . check ( item. owner_id . def_id , item_visibility, effective_vis)
1648- . generics ( )
1649- . predicates ( ) ;
1650-
1651- for variant in def. variants {
1652- for field in variant. data . fields ( ) {
1653- self . check ( field. def_id , item_visibility, effective_vis) . ty ( ) ;
1654- }
1655- }
1656- }
1657- }
1658- // Subitems of foreign modules have their own publicity.
1659- DefKind :: ForeignMod => {
1660- let item = tcx. hir_item ( id) ;
1661- if let hir:: ItemKind :: ForeignMod { items, .. } = item. kind {
1662- for & foreign_item in items {
1663- let foreign_item = tcx. hir_foreign_item ( foreign_item) ;
1664-
1665- let ev = self . get ( foreign_item. owner_id . def_id ) ;
1666- let vis = tcx. local_visibility ( foreign_item. owner_id . def_id ) ;
1667-
1668- if let ForeignItemKind :: Type = foreign_item. kind {
1669- self . check_unnameable ( foreign_item. owner_id . def_id , ev) ;
1670- }
1638+ self . check_unnameable ( def_id, effective_vis) ;
1639+ self . check ( def_id, item_visibility, effective_vis) . generics ( ) . predicates ( ) ;
16711640
1672- self . check ( foreign_item. owner_id . def_id , vis, ev)
1673- . generics ( )
1674- . predicates ( )
1675- . ty ( ) ;
1676- }
1641+ let adt = tcx. adt_def ( id. owner_id ) ;
1642+ for field in adt. all_fields ( ) {
1643+ self . check ( field. did . expect_local ( ) , item_visibility, effective_vis) . ty ( ) ;
16771644 }
16781645 }
16791646 // Subitems of structs and unions have their own publicity.
16801647 DefKind :: Struct | DefKind :: Union => {
1681- let item = tcx. hir_item ( id) ;
1682- if let hir:: ItemKind :: Struct ( _, _, ref struct_def)
1683- | hir:: ItemKind :: Union ( _, _, ref struct_def) = item. kind
1684- {
1685- self . check_unnameable ( item. owner_id . def_id , effective_vis) ;
1686- self . check ( item. owner_id . def_id , item_visibility, effective_vis)
1687- . generics ( )
1688- . predicates ( ) ;
1648+ self . check_unnameable ( def_id, effective_vis) ;
1649+ self . check ( def_id, item_visibility, effective_vis) . generics ( ) . predicates ( ) ;
16891650
1690- for field in struct_def. fields ( ) {
1691- let field_visibility = tcx. local_visibility ( field. def_id ) ;
1692- let field_ev = self . get ( field. def_id ) ;
1651+ let adt = tcx. adt_def ( id. owner_id ) ;
1652+ for field in adt. all_fields ( ) {
1653+ let visibility = min ( item_visibility, field. vis . expect_local ( ) , tcx) ;
1654+ let field_ev = self . get ( field. did . expect_local ( ) ) ;
16931655
1694- self . check (
1695- field. def_id ,
1696- min ( item_visibility, field_visibility, tcx) ,
1697- field_ev,
1698- )
1699- . ty ( ) ;
1700- }
1656+ self . check ( field. did . expect_local ( ) , visibility, field_ev) . ty ( ) ;
17011657 }
17021658 }
1659+ // Subitems of foreign modules have their own publicity.
1660+ DefKind :: ForeignMod => { }
17031661 // An inherent impl is public when its type is public
17041662 // Subitems of inherent impls have their own publicity.
17051663 // A trait impl is public when both its type and its trait are public
@@ -1755,6 +1713,19 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
17551713 _ => { }
17561714 }
17571715 }
1716+
1717+ fn check_foreign_item ( & mut self , id : ForeignItemId ) {
1718+ let tcx = self . tcx ;
1719+ let def_id = id. owner_id . def_id ;
1720+ let item_visibility = tcx. local_visibility ( def_id) ;
1721+ let effective_vis = self . get ( def_id) ;
1722+
1723+ if let DefKind :: ForeignTy = self . tcx . def_kind ( def_id) {
1724+ self . check_unnameable ( def_id, effective_vis) ;
1725+ }
1726+
1727+ self . check ( def_id, item_visibility, effective_vis) . generics ( ) . predicates ( ) . ty ( ) ;
1728+ }
17581729}
17591730
17601731pub fn provide ( providers : & mut Providers ) {
@@ -1783,20 +1754,13 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
17831754 if let Some ( body_id) = tcx. hir_maybe_body_owned_by ( def_id) {
17841755 visitor. visit_nested_body ( body_id. id ( ) ) ;
17851756 }
1786- }
17871757
1788- for id in module. free_items ( ) {
1789- if let ItemKind :: Impl ( i) = tcx. hir_item ( id) . kind {
1790- if let Some ( item) = i. of_trait {
1791- let trait_ref = tcx. impl_trait_ref ( id. owner_id . def_id ) . unwrap ( ) ;
1792- let trait_ref = trait_ref. instantiate_identity ( ) ;
1793- visitor. span = item. path . span ;
1794- let _ = visitor. visit_def_id (
1795- trait_ref. def_id ,
1796- "trait" ,
1797- & trait_ref. print_only_trait_path ( ) ,
1798- ) ;
1799- }
1758+ if let DefKind :: Impl { of_trait : true } = tcx. def_kind ( def_id) {
1759+ let trait_ref = tcx. impl_trait_ref ( def_id) . unwrap ( ) ;
1760+ let trait_ref = trait_ref. instantiate_identity ( ) ;
1761+ visitor. span = tcx. hir_expect_item ( def_id) . expect_impl ( ) . of_trait . unwrap ( ) . path . span ;
1762+ let _ =
1763+ visitor. visit_def_id ( trait_ref. def_id , "trait" , & trait_ref. print_only_trait_path ( ) ) ;
18001764 }
18011765 }
18021766}
@@ -1887,7 +1851,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
18871851 // Check for private types in public interfaces.
18881852 let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities } ;
18891853
1890- for id in tcx. hir_free_items ( ) {
1854+ let crate_items = tcx. hir_crate_items ( ( ) ) ;
1855+ for id in crate_items. free_items ( ) {
18911856 checker. check_item ( id) ;
18921857 }
1858+ for id in crate_items. foreign_items ( ) {
1859+ checker. check_foreign_item ( id) ;
1860+ }
18931861}
0 commit comments