@@ -24,7 +24,7 @@ use rustc_hir::{BodyId, Mutability};
2424use rustc_hir_analysis:: check:: intrinsic:: intrinsic_operation_unsafety;
2525use rustc_index:: vec:: IndexVec ;
2626use rustc_middle:: ty:: fast_reject:: SimplifiedType ;
27- use rustc_middle:: ty:: { self , TyCtxt } ;
27+ use rustc_middle:: ty:: { self , DefIdTree , TyCtxt } ;
2828use rustc_session:: Session ;
2929use rustc_span:: hygiene:: MacroKind ;
3030use rustc_span:: source_map:: DUMMY_SP ;
@@ -348,12 +348,12 @@ pub(crate) struct Item {
348348 /// Optional because not every item has a name, e.g. impls.
349349 pub ( crate ) name : Option < Symbol > ,
350350 pub ( crate ) attrs : Box < Attributes > ,
351- pub ( crate ) visibility : Visibility ,
352351 /// Information about this item that is specific to what kind of item it is.
353352 /// E.g., struct vs enum vs function.
354353 pub ( crate ) kind : Box < ItemKind > ,
355354 pub ( crate ) item_id : ItemId ,
356-
355+ /// This is the `DefId` of the `use` statement if the item was inlined.
356+ pub ( crate ) inline_stmt_id : Option < DefId > ,
357357 pub ( crate ) cfg : Option < Arc < Cfg > > ,
358358}
359359
@@ -364,9 +364,7 @@ impl fmt::Debug for Item {
364364 let alternate = f. alternate ( ) ;
365365 // hand-picked fields that don't bloat the logs too much
366366 let mut fmt = f. debug_struct ( "Item" ) ;
367- fmt. field ( "name" , & self . name )
368- . field ( "visibility" , & self . visibility )
369- . field ( "item_id" , & self . item_id ) ;
367+ fmt. field ( "name" , & self . name ) . field ( "item_id" , & self . item_id ) ;
370368 // allow printing the full item if someone really wants to
371369 if alternate {
372370 fmt. field ( "attrs" , & self . attrs ) . field ( "kind" , & self . kind ) . field ( "cfg" , & self . cfg ) ;
@@ -388,6 +386,15 @@ pub(crate) fn rustc_span(def_id: DefId, tcx: TyCtxt<'_>) -> Span {
388386 ) )
389387}
390388
389+ fn is_field_vis_inherited ( tcx : TyCtxt < ' _ > , def_id : DefId ) -> bool {
390+ let parent = tcx. parent ( def_id) ;
391+ match tcx. def_kind ( parent) {
392+ DefKind :: Struct | DefKind :: Union => false ,
393+ DefKind :: Variant => true ,
394+ parent_kind => panic ! ( "unexpected parent kind: {:?}" , parent_kind) ,
395+ }
396+ }
397+
391398impl Item {
392399 pub ( crate ) fn stability < ' tcx > ( & self , tcx : TyCtxt < ' tcx > ) -> Option < Stability > {
393400 self . item_id . as_def_id ( ) . and_then ( |did| tcx. lookup_stability ( did) )
@@ -462,7 +469,6 @@ impl Item {
462469 name,
463470 kind,
464471 Box :: new ( Attributes :: from_ast ( ast_attrs) ) ,
465- cx,
466472 ast_attrs. cfg ( cx. tcx , & cx. cache . hidden_cfg ) ,
467473 )
468474 }
@@ -472,21 +478,18 @@ impl Item {
472478 name : Option < Symbol > ,
473479 kind : ItemKind ,
474480 attrs : Box < Attributes > ,
475- cx : & mut DocContext < ' _ > ,
476481 cfg : Option < Arc < Cfg > > ,
477482 ) -> Item {
478483 trace ! ( "name={:?}, def_id={:?} cfg={:?}" , name, def_id, cfg) ;
479484
480- // Primitives and Keywords are written in the source code as private modules.
481- // The modules need to be private so that nobody actually uses them, but the
482- // keywords and primitives that they are documenting are public.
483- let visibility = if matches ! ( & kind, ItemKind :: KeywordItem | ItemKind :: PrimitiveItem ( ..) ) {
484- Visibility :: Public
485- } else {
486- clean_visibility ( cx. tcx . visibility ( def_id) )
487- } ;
488-
489- Item { item_id : def_id. into ( ) , kind : Box :: new ( kind) , name, attrs, visibility, cfg }
485+ Item {
486+ item_id : def_id. into ( ) ,
487+ kind : Box :: new ( kind) ,
488+ name,
489+ attrs,
490+ cfg,
491+ inline_stmt_id : None ,
492+ }
490493 }
491494
492495 /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
@@ -702,6 +705,51 @@ impl Item {
702705 } ;
703706 Some ( header)
704707 }
708+
709+ pub ( crate ) fn visibility ( & self , tcx : TyCtxt < ' _ > ) -> Visibility {
710+ let def_id = match self . item_id {
711+ // Anything but DefId *shouldn't* matter, but return a reasonable value anyway.
712+ ItemId :: Auto { .. } | ItemId :: Blanket { .. } => return Visibility :: Inherited ,
713+ // Primitives and Keywords are written in the source code as private modules.
714+ // The modules need to be private so that nobody actually uses them, but the
715+ // keywords and primitives that they are documenting are public.
716+ ItemId :: Primitive ( ..) => return Visibility :: Public ,
717+ ItemId :: DefId ( def_id) => def_id,
718+ } ;
719+
720+ match * self . kind {
721+ // Explication on `ItemId::Primitive` just above.
722+ ItemKind :: KeywordItem | ItemKind :: PrimitiveItem ( _) => return Visibility :: Public ,
723+ // Variant fields inherit their enum's visibility.
724+ StructFieldItem ( ..) if is_field_vis_inherited ( tcx, def_id) => {
725+ return Visibility :: Inherited ;
726+ }
727+ // Variants always inherit visibility
728+ VariantItem ( ..) => return Visibility :: Inherited ,
729+ // Trait items inherit the trait's visibility
730+ AssocConstItem ( ..) | TyAssocConstItem ( ..) | AssocTypeItem ( ..) | TyAssocTypeItem ( ..)
731+ | TyMethodItem ( ..) | MethodItem ( ..) => {
732+ let assoc_item = tcx. associated_item ( def_id) ;
733+ let is_trait_item = match assoc_item. container {
734+ ty:: TraitContainer => true ,
735+ ty:: ImplContainer => {
736+ // Trait impl items always inherit the impl's visibility --
737+ // we don't want to show `pub`.
738+ tcx. impl_trait_ref ( tcx. parent ( assoc_item. def_id ) ) . is_some ( )
739+ }
740+ } ;
741+ if is_trait_item {
742+ return Visibility :: Inherited ;
743+ }
744+ }
745+ _ => { }
746+ }
747+ let def_id = match self . inline_stmt_id {
748+ Some ( inlined) => inlined,
749+ None => def_id,
750+ } ;
751+ clean_visibility ( tcx. visibility ( def_id) )
752+ }
705753}
706754
707755#[ derive( Clone , Debug ) ]
0 commit comments