@@ -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
@@ -1644,66 +1639,29 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
16441639 self . check ( def_id, item_visibility, effective_vis) . generics ( ) . predicates ( ) ;
16451640 }
16461641 DefKind :: Enum => {
1647- let item = tcx. hir_item ( id) ;
1648- if let hir:: ItemKind :: Enum ( _, _, ref def) = item. kind {
1649- self . check_unnameable ( item. owner_id . def_id , effective_vis) ;
1650-
1651- self . check ( item. owner_id . def_id , item_visibility, effective_vis)
1652- . generics ( )
1653- . predicates ( ) ;
1654-
1655- for variant in def. variants {
1656- for field in variant. data . fields ( ) {
1657- self . check ( field. def_id , item_visibility, effective_vis) . ty ( ) ;
1658- }
1659- }
1660- }
1661- }
1662- // Subitems of foreign modules have their own publicity.
1663- DefKind :: ForeignMod => {
1664- let item = tcx. hir_item ( id) ;
1665- if let hir:: ItemKind :: ForeignMod { items, .. } = item. kind {
1666- for & foreign_item in items {
1667- let foreign_item = tcx. hir_foreign_item ( foreign_item) ;
1668-
1669- let ev = self . get ( foreign_item. owner_id . def_id ) ;
1670- let vis = tcx. local_visibility ( foreign_item. owner_id . def_id ) ;
1671-
1672- if let ForeignItemKind :: Type = foreign_item. kind {
1673- self . check_unnameable ( foreign_item. owner_id . def_id , ev) ;
1674- }
1642+ self . check_unnameable ( def_id, effective_vis) ;
1643+ self . check ( def_id, item_visibility, effective_vis) . generics ( ) . predicates ( ) ;
16751644
1676- self . check ( foreign_item. owner_id . def_id , vis, ev)
1677- . generics ( )
1678- . predicates ( )
1679- . ty ( ) ;
1680- }
1645+ let adt = tcx. adt_def ( id. owner_id ) ;
1646+ for field in adt. all_fields ( ) {
1647+ self . check ( field. did . expect_local ( ) , item_visibility, effective_vis) . ty ( ) ;
16811648 }
16821649 }
16831650 // Subitems of structs and unions have their own publicity.
16841651 DefKind :: Struct | DefKind :: Union => {
1685- let item = tcx. hir_item ( id) ;
1686- if let hir:: ItemKind :: Struct ( _, _, ref struct_def)
1687- | hir:: ItemKind :: Union ( _, _, ref struct_def) = item. kind
1688- {
1689- self . check_unnameable ( item. owner_id . def_id , effective_vis) ;
1690- self . check ( item. owner_id . def_id , item_visibility, effective_vis)
1691- . generics ( )
1692- . predicates ( ) ;
1652+ self . check_unnameable ( def_id, effective_vis) ;
1653+ self . check ( def_id, item_visibility, effective_vis) . generics ( ) . predicates ( ) ;
16931654
1694- for field in struct_def. fields ( ) {
1695- let field_visibility = tcx. local_visibility ( field. def_id ) ;
1696- let field_ev = self . get ( field. def_id ) ;
1655+ let adt = tcx. adt_def ( id. owner_id ) ;
1656+ for field in adt. all_fields ( ) {
1657+ let visibility = min ( item_visibility, field. vis . expect_local ( ) , tcx) ;
1658+ let field_ev = self . get ( field. did . expect_local ( ) ) ;
16971659
1698- self . check (
1699- field. def_id ,
1700- min ( item_visibility, field_visibility, tcx) ,
1701- field_ev,
1702- )
1703- . ty ( ) ;
1704- }
1660+ self . check ( field. did . expect_local ( ) , visibility, field_ev) . ty ( ) ;
17051661 }
17061662 }
1663+ // Subitems of foreign modules have their own publicity.
1664+ DefKind :: ForeignMod => { }
17071665 // An inherent impl is public when its type is public
17081666 // Subitems of inherent impls have their own publicity.
17091667 // A trait impl is public when both its type and its trait are public
@@ -1763,6 +1721,19 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
17631721 _ => { }
17641722 }
17651723 }
1724+
1725+ fn check_foreign_item ( & mut self , id : ForeignItemId ) {
1726+ let tcx = self . tcx ;
1727+ let def_id = id. owner_id . def_id ;
1728+ let item_visibility = tcx. local_visibility ( def_id) ;
1729+ let effective_vis = self . get ( def_id) ;
1730+
1731+ if let DefKind :: ForeignTy = self . tcx . def_kind ( def_id) {
1732+ self . check_unnameable ( def_id, effective_vis) ;
1733+ }
1734+
1735+ self . check ( def_id, item_visibility, effective_vis) . generics ( ) . predicates ( ) . ty ( ) ;
1736+ }
17661737}
17671738
17681739pub fn provide ( providers : & mut Providers ) {
@@ -1791,20 +1762,13 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
17911762 if let Some ( body_id) = tcx. hir_maybe_body_owned_by ( def_id) {
17921763 visitor. visit_nested_body ( body_id. id ( ) ) ;
17931764 }
1794- }
17951765
1796- for id in module. free_items ( ) {
1797- if let ItemKind :: Impl ( i) = tcx. hir_item ( id) . kind {
1798- if let Some ( item) = i. of_trait {
1799- let trait_ref = tcx. impl_trait_ref ( id. owner_id . def_id ) . unwrap ( ) ;
1800- let trait_ref = trait_ref. instantiate_identity ( ) ;
1801- visitor. span = item. path . span ;
1802- let _ = visitor. visit_def_id (
1803- trait_ref. def_id ,
1804- "trait" ,
1805- & trait_ref. print_only_trait_path ( ) ,
1806- ) ;
1807- }
1766+ if let DefKind :: Impl { of_trait : true } = tcx. def_kind ( def_id) {
1767+ let trait_ref = tcx. impl_trait_ref ( def_id) . unwrap ( ) ;
1768+ let trait_ref = trait_ref. instantiate_identity ( ) ;
1769+ visitor. span = tcx. hir_expect_item ( def_id) . expect_impl ( ) . of_trait . unwrap ( ) . path . span ;
1770+ let _ =
1771+ visitor. visit_def_id ( trait_ref. def_id , "trait" , & trait_ref. print_only_trait_path ( ) ) ;
18081772 }
18091773 }
18101774}
@@ -1895,7 +1859,11 @@ fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
18951859 // Check for private types in public interfaces.
18961860 let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities } ;
18971861
1898- for id in tcx. hir_free_items ( ) {
1862+ let crate_items = tcx. hir_crate_items ( ( ) ) ;
1863+ for id in crate_items. free_items ( ) {
18991864 checker. check_item ( id) ;
19001865 }
1866+ for id in crate_items. foreign_items ( ) {
1867+ checker. check_foreign_item ( id) ;
1868+ }
19011869}
0 commit comments