@@ -24,9 +24,9 @@ use rustc_data_structures::fx::FxHashSet;
24
24
use rustc_data_structures:: intern:: Interned ;
25
25
use rustc_errors:: { MultiSpan , listify} ;
26
26
use rustc_hir:: def:: { DefKind , Res } ;
27
- use rustc_hir:: def_id:: { CRATE_DEF_ID , DefId , LocalDefId , LocalModDefId } ;
27
+ use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId } ;
28
28
use rustc_hir:: intravisit:: { self , InferKind , Visitor } ;
29
- use rustc_hir:: { AmbigArg , ForeignItemId , ItemId , PatKind } ;
29
+ use rustc_hir:: { AmbigArg , ForeignItemId , ItemId , OwnerId , PatKind } ;
30
30
use rustc_middle:: middle:: privacy:: { EffectiveVisibilities , EffectiveVisibility , Level } ;
31
31
use rustc_middle:: query:: Providers ;
32
32
use rustc_middle:: ty:: print:: PrintTraitRefExt as _;
@@ -636,58 +636,62 @@ impl<'tcx> EmbargoVisitor<'tcx> {
636
636
}
637
637
}
638
638
639
- impl < ' tcx > Visitor < ' tcx > for EmbargoVisitor < ' tcx > {
640
- fn visit_item ( & mut self , item : & ' tcx hir :: Item < ' tcx > ) {
639
+ impl < ' tcx > EmbargoVisitor < ' tcx > {
640
+ fn check_def_id ( & mut self , owner_id : OwnerId ) {
641
641
// Update levels of nested things and mark all items
642
642
// in interfaces of reachable items as reachable.
643
- let item_ev = self . get ( item . owner_id . def_id ) ;
644
- match item . kind {
643
+ let item_ev = self . get ( owner_id. def_id ) ;
644
+ match self . tcx . def_kind ( owner_id ) {
645
645
// The interface is empty, and no nested items.
646
- hir:: ItemKind :: Use ( ..)
647
- | hir:: ItemKind :: ExternCrate ( ..)
648
- | hir:: ItemKind :: GlobalAsm { .. } => { }
646
+ DefKind :: Use | DefKind :: ExternCrate | DefKind :: GlobalAsm => { }
649
647
// The interface is empty, and all nested items are processed by `visit_item`.
650
- hir :: ItemKind :: Mod ( .. ) => { }
651
- hir :: ItemKind :: Macro ( _ , macro_def , _ ) => {
648
+ DefKind :: Mod => { }
649
+ DefKind :: Macro { .. } => {
652
650
if let Some ( item_ev) = item_ev {
653
- self . update_reachability_from_macro ( item. owner_id . def_id , macro_def, item_ev) ;
651
+ let ( _, macro_def, _) =
652
+ self . tcx . hir_expect_item ( owner_id. def_id ) . expect_macro ( ) ;
653
+ self . update_reachability_from_macro ( owner_id. def_id , macro_def, item_ev) ;
654
654
}
655
655
}
656
- hir:: ItemKind :: Const ( ..)
657
- | hir:: ItemKind :: Static ( ..)
658
- | hir:: ItemKind :: Fn { .. }
659
- | hir:: ItemKind :: TyAlias ( ..) => {
656
+ DefKind :: ForeignTy
657
+ | DefKind :: Const
658
+ | DefKind :: Static { .. }
659
+ | DefKind :: Fn
660
+ | DefKind :: TyAlias => {
660
661
if let Some ( item_ev) = item_ev {
661
- self . reach ( item . owner_id . def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
662
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
662
663
}
663
664
}
664
- hir :: ItemKind :: Trait ( .. , trait_item_refs ) => {
665
+ DefKind :: Trait => {
665
666
if let Some ( item_ev) = item_ev {
666
- self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
667
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
668
+
669
+ for assoc_item in self . tcx . associated_items ( owner_id) . in_definition_order ( ) {
670
+ if assoc_item. is_impl_trait_in_trait ( ) {
671
+ continue ;
672
+ }
667
673
668
- for trait_item_ref in trait_item_refs {
669
- self . update ( trait_item_ref . owner_id . def_id , item_ev, Level :: Reachable ) ;
674
+ let def_id = assoc_item . def_id . expect_local ( ) ;
675
+ self . update ( def_id, item_ev, Level :: Reachable ) ;
670
676
671
677
let tcx = self . tcx ;
672
- let mut reach = self . reach ( trait_item_ref . owner_id . def_id , item_ev) ;
678
+ let mut reach = self . reach ( def_id, item_ev) ;
673
679
reach. generics ( ) . predicates ( ) ;
674
680
675
- if let DefKind :: AssocTy = tcx. def_kind ( trait_item_ref. owner_id )
676
- && !tcx. defaultness ( trait_item_ref. owner_id ) . has_value ( )
677
- {
681
+ if assoc_item. is_type ( ) && !assoc_item. defaultness ( tcx) . has_value ( ) {
678
682
// No type to visit.
679
683
} else {
680
684
reach. ty ( ) ;
681
685
}
682
686
}
683
687
}
684
688
}
685
- hir :: ItemKind :: TraitAlias ( .. ) => {
689
+ DefKind :: TraitAlias => {
686
690
if let Some ( item_ev) = item_ev {
687
- self . reach ( item . owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
691
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
688
692
}
689
693
}
690
- hir :: ItemKind :: Impl ( impl_ ) => {
694
+ DefKind :: Impl { of_trait } => {
691
695
// Type inference is very smart sometimes. It can make an impl reachable even some
692
696
// components of its type or trait are unreachable. E.g. methods of
693
697
// `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
@@ -699,85 +703,100 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
699
703
// without knowing both "shallow" version of its self type and "shallow" version of
700
704
// its trait if it exists (which require reaching the `DefId`s in them).
701
705
let item_ev = EffectiveVisibility :: of_impl :: < true > (
702
- item . owner_id . def_id ,
706
+ owner_id. def_id ,
703
707
self . tcx ,
704
708
& self . effective_visibilities ,
705
709
) ;
706
710
707
- self . update_eff_vis ( item. owner_id . def_id , item_ev, None , Level :: Direct ) ;
711
+ self . update_eff_vis ( owner_id. def_id , item_ev, None , Level :: Direct ) ;
712
+
713
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) . trait_ref ( ) ;
708
714
709
- self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) . trait_ref ( ) ;
715
+ for assoc_item in self . tcx . associated_items ( owner_id) . in_definition_order ( ) {
716
+ if assoc_item. is_impl_trait_in_trait ( ) {
717
+ continue ;
718
+ }
710
719
711
- for impl_item_ref in impl_. items {
712
- let def_id = impl_item_ref. owner_id . def_id ;
720
+ let def_id = assoc_item. def_id . expect_local ( ) ;
713
721
let max_vis =
714
- impl_ . of_trait . is_none ( ) . then ( || self . tcx . local_visibility ( def_id) ) ;
722
+ if of_trait { None } else { Some ( self . tcx . local_visibility ( def_id) ) } ;
715
723
self . update_eff_vis ( def_id, item_ev, max_vis, Level :: Direct ) ;
716
724
717
725
if let Some ( impl_item_ev) = self . get ( def_id) {
718
726
self . reach ( def_id, impl_item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
719
727
}
720
728
}
721
729
}
722
- hir :: ItemKind :: Enum ( _ , _ , ref def ) => {
730
+ DefKind :: Enum => {
723
731
if let Some ( item_ev) = item_ev {
724
- self . reach ( item . owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
732
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
725
733
}
726
- for variant in def. variants {
734
+ let def = self . tcx . adt_def ( owner_id) ;
735
+ for variant in def. variants ( ) {
727
736
if let Some ( item_ev) = item_ev {
728
- self . update ( variant. def_id , item_ev, Level :: Reachable ) ;
737
+ self . update ( variant. def_id . expect_local ( ) , item_ev, Level :: Reachable ) ;
729
738
}
730
739
731
- if let Some ( variant_ev) = self . get ( variant. def_id ) {
732
- if let Some ( ctor_def_id) = variant. data . ctor_def_id ( ) {
733
- self . update ( ctor_def_id, variant_ev, Level :: Reachable ) ;
740
+ if let Some ( variant_ev) = self . get ( variant. def_id . expect_local ( ) ) {
741
+ if let Some ( ctor_def_id) = variant. ctor_def_id ( ) {
742
+ self . update ( ctor_def_id. expect_local ( ) , variant_ev, Level :: Reachable ) ;
734
743
}
735
744
736
- for field in variant. data . fields ( ) {
737
- self . update ( field. def_id , variant_ev, Level :: Reachable ) ;
738
- self . reach ( field. def_id , variant_ev) . ty ( ) ;
745
+ for field in variant. fields . iter ( ) {
746
+ let field = field. did . expect_local ( ) ;
747
+ self . update ( field, variant_ev, Level :: Reachable ) ;
748
+ self . reach ( field, variant_ev) . ty ( ) ;
739
749
}
740
750
// Corner case: if the variant is reachable, but its
741
751
// enum is not, make the enum reachable as well.
742
- self . reach ( item . owner_id . def_id , variant_ev) . ty ( ) ;
752
+ self . reach ( owner_id. def_id , variant_ev) . ty ( ) ;
743
753
}
744
- if let Some ( ctor_def_id) = variant. data . ctor_def_id ( ) {
745
- if let Some ( ctor_ev) = self . get ( ctor_def_id) {
746
- self . reach ( item . owner_id . def_id , ctor_ev) . ty ( ) ;
754
+ if let Some ( ctor_def_id) = variant. ctor_def_id ( ) {
755
+ if let Some ( ctor_ev) = self . get ( ctor_def_id. expect_local ( ) ) {
756
+ self . reach ( owner_id. def_id , ctor_ev) . ty ( ) ;
747
757
}
748
758
}
749
759
}
750
760
}
751
- hir:: ItemKind :: ForeignMod { items, .. } => {
752
- for foreign_item in items {
753
- if let Some ( foreign_item_ev) = self . get ( foreign_item. owner_id . def_id ) {
754
- self . reach ( foreign_item. owner_id . def_id , foreign_item_ev)
755
- . generics ( )
756
- . predicates ( )
757
- . ty ( ) ;
758
- }
759
- }
760
- }
761
- hir:: ItemKind :: Struct ( _, _, ref struct_def)
762
- | hir:: ItemKind :: Union ( _, _, ref struct_def) => {
761
+ DefKind :: Struct | DefKind :: Union => {
762
+ let def = self . tcx . adt_def ( owner_id) . non_enum_variant ( ) ;
763
763
if let Some ( item_ev) = item_ev {
764
- self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
765
- for field in struct_def. fields ( ) {
766
- self . update ( field. def_id , item_ev, Level :: Reachable ) ;
767
- if let Some ( field_ev) = self . get ( field. def_id ) {
768
- self . reach ( field. def_id , field_ev) . ty ( ) ;
764
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
765
+ for field in def. fields . iter ( ) {
766
+ let field = field. did . expect_local ( ) ;
767
+ self . update ( field, item_ev, Level :: Reachable ) ;
768
+ if let Some ( field_ev) = self . get ( field) {
769
+ self . reach ( field, field_ev) . ty ( ) ;
769
770
}
770
771
}
771
772
}
772
- if let Some ( ctor_def_id) = struct_def . ctor_def_id ( ) {
773
+ if let Some ( ctor_def_id) = def . ctor_def_id ( ) {
773
774
if let Some ( item_ev) = item_ev {
774
- self . update ( ctor_def_id, item_ev, Level :: Reachable ) ;
775
+ self . update ( ctor_def_id. expect_local ( ) , item_ev, Level :: Reachable ) ;
775
776
}
776
- if let Some ( ctor_ev) = self . get ( ctor_def_id) {
777
- self . reach ( item . owner_id . def_id , ctor_ev) . ty ( ) ;
777
+ if let Some ( ctor_ev) = self . get ( ctor_def_id. expect_local ( ) ) {
778
+ self . reach ( owner_id. def_id , ctor_ev) . ty ( ) ;
778
779
}
779
780
}
780
781
}
782
+ // Contents are checked directly.
783
+ DefKind :: ForeignMod => { }
784
+ DefKind :: Field
785
+ | DefKind :: Variant
786
+ | DefKind :: AssocFn
787
+ | DefKind :: AssocTy
788
+ | DefKind :: AssocConst
789
+ | DefKind :: TyParam
790
+ | DefKind :: AnonConst
791
+ | DefKind :: InlineConst
792
+ | DefKind :: OpaqueTy
793
+ | DefKind :: Closure
794
+ | DefKind :: SyntheticCoroutineBody
795
+ | DefKind :: ConstParam
796
+ | DefKind :: LifetimeParam
797
+ | DefKind :: Ctor ( ..) => {
798
+ bug ! ( "should be checked while checking parent" )
799
+ }
781
800
}
782
801
}
783
802
}
@@ -838,7 +857,7 @@ pub struct TestReachabilityVisitor<'a, 'tcx> {
838
857
}
839
858
840
859
impl < ' a , ' tcx > TestReachabilityVisitor < ' a , ' tcx > {
841
- fn effective_visibility_diagnostic ( & mut self , def_id : LocalDefId ) {
860
+ fn effective_visibility_diagnostic ( & self , def_id : LocalDefId ) {
842
861
if self . tcx . has_attr ( def_id, sym:: rustc_effective_visibility) {
843
862
let mut error_msg = String :: new ( ) ;
844
863
let span = self . tcx . def_span ( def_id. to_def_id ( ) ) ;
@@ -858,43 +877,35 @@ impl<'a, 'tcx> TestReachabilityVisitor<'a, 'tcx> {
858
877
}
859
878
}
860
879
861
- impl < ' a , ' tcx > Visitor < ' tcx > for TestReachabilityVisitor < ' a , ' tcx > {
862
- fn visit_item ( & mut self , item : & ' tcx hir :: Item < ' tcx > ) {
863
- self . effective_visibility_diagnostic ( item . owner_id . def_id ) ;
880
+ impl < ' a , ' tcx > TestReachabilityVisitor < ' a , ' tcx > {
881
+ fn check_def_id ( & self , owner_id : OwnerId ) {
882
+ self . effective_visibility_diagnostic ( owner_id. def_id ) ;
864
883
865
- match item. kind {
866
- hir:: ItemKind :: Enum ( _, _, ref def) => {
867
- for variant in def. variants . iter ( ) {
868
- self . effective_visibility_diagnostic ( variant. def_id ) ;
869
- if let Some ( ctor_def_id) = variant. data . ctor_def_id ( ) {
870
- self . effective_visibility_diagnostic ( ctor_def_id) ;
884
+ match self . tcx . def_kind ( owner_id) {
885
+ DefKind :: Enum => {
886
+ let def = self . tcx . adt_def ( owner_id. def_id ) ;
887
+ for variant in def. variants ( ) {
888
+ self . effective_visibility_diagnostic ( variant. def_id . expect_local ( ) ) ;
889
+ if let Some ( ctor_def_id) = variant. ctor_def_id ( ) {
890
+ self . effective_visibility_diagnostic ( ctor_def_id. expect_local ( ) ) ;
871
891
}
872
- for field in variant. data . fields ( ) {
873
- self . effective_visibility_diagnostic ( field. def_id ) ;
892
+ for field in variant. fields . iter ( ) {
893
+ self . effective_visibility_diagnostic ( field. did . expect_local ( ) ) ;
874
894
}
875
895
}
876
896
}
877
- hir:: ItemKind :: Struct ( _, _, ref def) | hir:: ItemKind :: Union ( _, _, ref def) => {
897
+ DefKind :: Struct | DefKind :: Union => {
898
+ let def = self . tcx . adt_def ( owner_id. def_id ) . non_enum_variant ( ) ;
878
899
if let Some ( ctor_def_id) = def. ctor_def_id ( ) {
879
- self . effective_visibility_diagnostic ( ctor_def_id) ;
900
+ self . effective_visibility_diagnostic ( ctor_def_id. expect_local ( ) ) ;
880
901
}
881
- for field in def. fields ( ) {
882
- self . effective_visibility_diagnostic ( field. def_id ) ;
902
+ for field in def. fields . iter ( ) {
903
+ self . effective_visibility_diagnostic ( field. did . expect_local ( ) ) ;
883
904
}
884
905
}
885
906
_ => { }
886
907
}
887
908
}
888
-
889
- fn visit_trait_item ( & mut self , item : & ' tcx hir:: TraitItem < ' tcx > ) {
890
- self . effective_visibility_diagnostic ( item. owner_id . def_id ) ;
891
- }
892
- fn visit_impl_item ( & mut self , item : & ' tcx hir:: ImplItem < ' tcx > ) {
893
- self . effective_visibility_diagnostic ( item. owner_id . def_id ) ;
894
- }
895
- fn visit_foreign_item ( & mut self , item : & ' tcx hir:: ForeignItem < ' tcx > ) {
896
- self . effective_visibility_diagnostic ( item. owner_id . def_id ) ;
897
- }
898
909
}
899
910
900
911
//////////////////////////////////////////////////////////////////////////////////////
@@ -1835,8 +1846,14 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
1835
1846
visitor. changed = false ;
1836
1847
}
1837
1848
1849
+ let crate_items = tcx. hir_crate_items ( ( ) ) ;
1838
1850
loop {
1839
- tcx. hir_visit_all_item_likes_in_crate ( & mut visitor) ;
1851
+ for id in crate_items. free_items ( ) {
1852
+ visitor. check_def_id ( id. owner_id ) ;
1853
+ }
1854
+ for id in crate_items. foreign_items ( ) {
1855
+ visitor. check_def_id ( id. owner_id ) ;
1856
+ }
1840
1857
if visitor. changed {
1841
1858
visitor. changed = false ;
1842
1859
} else {
@@ -1845,10 +1862,11 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
1845
1862
}
1846
1863
visitor. effective_visibilities . check_invariants ( tcx) ;
1847
1864
1848
- let mut check_visitor =
1865
+ let check_visitor =
1849
1866
TestReachabilityVisitor { tcx, effective_visibilities : & visitor. effective_visibilities } ;
1850
- check_visitor. effective_visibility_diagnostic ( CRATE_DEF_ID ) ;
1851
- tcx. hir_visit_all_item_likes_in_crate ( & mut check_visitor) ;
1867
+ for id in crate_items. owners ( ) {
1868
+ check_visitor. check_def_id ( id) ;
1869
+ }
1852
1870
1853
1871
tcx. arena . alloc ( visitor. effective_visibilities )
1854
1872
}
0 commit comments