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