@@ -24,7 +24,7 @@ use rustc_hir::{BodyId, Mutability};
24
24
use rustc_hir_analysis:: check:: intrinsic:: intrinsic_operation_unsafety;
25
25
use rustc_index:: vec:: IndexVec ;
26
26
use rustc_middle:: ty:: fast_reject:: SimplifiedType ;
27
- use rustc_middle:: ty:: { self , TyCtxt } ;
27
+ use rustc_middle:: ty:: { self , DefIdTree , TyCtxt } ;
28
28
use rustc_session:: Session ;
29
29
use rustc_span:: hygiene:: MacroKind ;
30
30
use rustc_span:: source_map:: DUMMY_SP ;
@@ -348,12 +348,12 @@ pub(crate) struct Item {
348
348
/// Optional because not every item has a name, e.g. impls.
349
349
pub ( crate ) name : Option < Symbol > ,
350
350
pub ( crate ) attrs : Box < Attributes > ,
351
- pub ( crate ) visibility : Visibility ,
352
351
/// Information about this item that is specific to what kind of item it is.
353
352
/// E.g., struct vs enum vs function.
354
353
pub ( crate ) kind : Box < ItemKind > ,
355
354
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 > ,
357
357
pub ( crate ) cfg : Option < Arc < Cfg > > ,
358
358
}
359
359
@@ -364,9 +364,7 @@ impl fmt::Debug for Item {
364
364
let alternate = f. alternate ( ) ;
365
365
// hand-picked fields that don't bloat the logs too much
366
366
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 ) ;
370
368
// allow printing the full item if someone really wants to
371
369
if alternate {
372
370
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 {
388
386
) )
389
387
}
390
388
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
+
391
398
impl Item {
392
399
pub ( crate ) fn stability < ' tcx > ( & self , tcx : TyCtxt < ' tcx > ) -> Option < Stability > {
393
400
self . item_id . as_def_id ( ) . and_then ( |did| tcx. lookup_stability ( did) )
@@ -462,7 +469,6 @@ impl Item {
462
469
name,
463
470
kind,
464
471
Box :: new ( Attributes :: from_ast ( ast_attrs) ) ,
465
- cx,
466
472
ast_attrs. cfg ( cx. tcx , & cx. cache . hidden_cfg ) ,
467
473
)
468
474
}
@@ -472,21 +478,18 @@ impl Item {
472
478
name : Option < Symbol > ,
473
479
kind : ItemKind ,
474
480
attrs : Box < Attributes > ,
475
- cx : & mut DocContext < ' _ > ,
476
481
cfg : Option < Arc < Cfg > > ,
477
482
) -> Item {
478
483
trace ! ( "name={:?}, def_id={:?} cfg={:?}" , name, def_id, cfg) ;
479
484
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
+ }
490
493
}
491
494
492
495
/// Finds all `doc` attributes as NameValues and returns their corresponding values, joined
@@ -702,6 +705,51 @@ impl Item {
702
705
} ;
703
706
Some ( header)
704
707
}
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
+ }
705
753
}
706
754
707
755
#[ derive( Clone , Debug ) ]
0 commit comments