@@ -26,9 +26,9 @@ use rustc_errors::{MultiSpan, listify};
26
26
use rustc_hir as hir;
27
27
use rustc_hir:: attrs:: AttributeKind ;
28
28
use rustc_hir:: def:: { DefKind , Res } ;
29
- use rustc_hir:: def_id:: { CRATE_DEF_ID , DefId , LocalDefId , LocalModDefId } ;
29
+ use rustc_hir:: def_id:: { DefId , LocalDefId , LocalModDefId } ;
30
30
use rustc_hir:: intravisit:: { self , InferKind , Visitor } ;
31
- use rustc_hir:: { AmbigArg , ForeignItemId , ItemId , PatKind , find_attr} ;
31
+ use rustc_hir:: { AmbigArg , ForeignItemId , ItemId , OwnerId , PatKind , find_attr} ;
32
32
use rustc_middle:: middle:: privacy:: { EffectiveVisibilities , EffectiveVisibility , Level } ;
33
33
use rustc_middle:: query:: Providers ;
34
34
use rustc_middle:: ty:: print:: PrintTraitRefExt as _;
@@ -599,7 +599,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
599
599
DefKind :: Struct | DefKind :: Union => {
600
600
// While structs and unions have type privacy, their fields do not.
601
601
let struct_def = self . tcx . adt_def ( def_id) ;
602
- for field in struct_def. non_enum_variant ( ) . fields . iter ( ) {
602
+ for field in & struct_def. non_enum_variant ( ) . fields {
603
603
let def_id = field. did . expect_local ( ) ;
604
604
let field_vis = self . tcx . local_visibility ( def_id) ;
605
605
if field_vis. is_accessible_from ( module, self . tcx ) {
@@ -637,58 +637,62 @@ impl<'tcx> EmbargoVisitor<'tcx> {
637
637
}
638
638
}
639
639
640
- impl < ' tcx > Visitor < ' tcx > for EmbargoVisitor < ' tcx > {
641
- fn visit_item ( & mut self , item : & ' tcx hir :: Item < ' tcx > ) {
640
+ impl < ' tcx > EmbargoVisitor < ' tcx > {
641
+ fn check_def_id ( & mut self , owner_id : OwnerId ) {
642
642
// Update levels of nested things and mark all items
643
643
// in interfaces of reachable items as reachable.
644
- let item_ev = self . get ( item . owner_id . def_id ) ;
645
- match item . kind {
644
+ let item_ev = self . get ( owner_id. def_id ) ;
645
+ match self . tcx . def_kind ( owner_id ) {
646
646
// The interface is empty, and no nested items.
647
- hir:: ItemKind :: Use ( ..)
648
- | hir:: ItemKind :: ExternCrate ( ..)
649
- | hir:: ItemKind :: GlobalAsm { .. } => { }
650
- // The interface is empty, and all nested items are processed by `visit_item`.
651
- hir:: ItemKind :: Mod ( ..) => { }
652
- hir:: ItemKind :: Macro ( _, macro_def, _) => {
647
+ DefKind :: Use | DefKind :: ExternCrate | DefKind :: GlobalAsm => { }
648
+ // The interface is empty, and all nested items are processed by `check_def_id`.
649
+ DefKind :: Mod => { }
650
+ DefKind :: Macro { .. } => {
653
651
if let Some ( item_ev) = item_ev {
654
- self . update_reachability_from_macro ( item. owner_id . def_id , macro_def, item_ev) ;
652
+ let ( _, macro_def, _) =
653
+ self . tcx . hir_expect_item ( owner_id. def_id ) . expect_macro ( ) ;
654
+ self . update_reachability_from_macro ( owner_id. def_id , macro_def, item_ev) ;
655
655
}
656
656
}
657
- hir:: ItemKind :: Const ( ..)
658
- | hir:: ItemKind :: Static ( ..)
659
- | hir:: ItemKind :: Fn { .. }
660
- | hir:: ItemKind :: TyAlias ( ..) => {
657
+ DefKind :: ForeignTy
658
+ | DefKind :: Const
659
+ | DefKind :: Static { .. }
660
+ | DefKind :: Fn
661
+ | DefKind :: TyAlias => {
661
662
if let Some ( item_ev) = item_ev {
662
- self . reach ( item . owner_id . def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
663
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
663
664
}
664
665
}
665
- hir :: ItemKind :: Trait ( .. , trait_item_refs ) => {
666
+ DefKind :: Trait => {
666
667
if let Some ( item_ev) = item_ev {
667
- self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
668
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
669
+
670
+ for assoc_item in self . tcx . associated_items ( owner_id) . in_definition_order ( ) {
671
+ if assoc_item. is_impl_trait_in_trait ( ) {
672
+ continue ;
673
+ }
668
674
669
- for trait_item_ref in trait_item_refs {
670
- self . update ( trait_item_ref . owner_id . def_id , item_ev, Level :: Reachable ) ;
675
+ let def_id = assoc_item . def_id . expect_local ( ) ;
676
+ self . update ( def_id, item_ev, Level :: Reachable ) ;
671
677
672
678
let tcx = self . tcx ;
673
- let mut reach = self . reach ( trait_item_ref . owner_id . def_id , item_ev) ;
679
+ let mut reach = self . reach ( def_id, item_ev) ;
674
680
reach. generics ( ) . predicates ( ) ;
675
681
676
- if let DefKind :: AssocTy = tcx. def_kind ( trait_item_ref. owner_id )
677
- && !tcx. defaultness ( trait_item_ref. owner_id ) . has_value ( )
678
- {
682
+ if assoc_item. is_type ( ) && !assoc_item. defaultness ( tcx) . has_value ( ) {
679
683
// No type to visit.
680
684
} else {
681
685
reach. ty ( ) ;
682
686
}
683
687
}
684
688
}
685
689
}
686
- hir :: ItemKind :: TraitAlias ( .. ) => {
690
+ DefKind :: TraitAlias => {
687
691
if let Some ( item_ev) = item_ev {
688
- self . reach ( item . owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
692
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
689
693
}
690
694
}
691
- hir :: ItemKind :: Impl ( impl_ ) => {
695
+ DefKind :: Impl { of_trait } => {
692
696
// Type inference is very smart sometimes. It can make an impl reachable even some
693
697
// components of its type or trait are unreachable. E.g. methods of
694
698
// `impl ReachableTrait<UnreachableTy> for ReachableTy<UnreachableTy> { ... }`
@@ -700,85 +704,100 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> {
700
704
// without knowing both "shallow" version of its self type and "shallow" version of
701
705
// its trait if it exists (which require reaching the `DefId`s in them).
702
706
let item_ev = EffectiveVisibility :: of_impl :: < true > (
703
- item . owner_id . def_id ,
707
+ owner_id. def_id ,
704
708
self . tcx ,
705
709
& self . effective_visibilities ,
706
710
) ;
707
711
708
- self . update_eff_vis ( item. owner_id . def_id , item_ev, None , Level :: Direct ) ;
712
+ self . update_eff_vis ( owner_id. def_id , item_ev, None , Level :: Direct ) ;
713
+
714
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) . trait_ref ( ) ;
709
715
710
- self . reach ( item. owner_id . def_id , item_ev) . generics ( ) . predicates ( ) . ty ( ) . trait_ref ( ) ;
716
+ for assoc_item in self . tcx . associated_items ( owner_id) . in_definition_order ( ) {
717
+ if assoc_item. is_impl_trait_in_trait ( ) {
718
+ continue ;
719
+ }
711
720
712
- for impl_item_ref in impl_. items {
713
- let def_id = impl_item_ref. owner_id . def_id ;
721
+ let def_id = assoc_item. def_id . expect_local ( ) ;
714
722
let max_vis =
715
- impl_ . of_trait . is_none ( ) . then ( || self . tcx . local_visibility ( def_id) ) ;
723
+ if of_trait { None } else { Some ( self . tcx . local_visibility ( def_id) ) } ;
716
724
self . update_eff_vis ( def_id, item_ev, max_vis, Level :: Direct ) ;
717
725
718
726
if let Some ( impl_item_ev) = self . get ( def_id) {
719
727
self . reach ( def_id, impl_item_ev) . generics ( ) . predicates ( ) . ty ( ) ;
720
728
}
721
729
}
722
730
}
723
- hir :: ItemKind :: Enum ( _ , _ , ref def ) => {
731
+ DefKind :: Enum => {
724
732
if let Some ( item_ev) = item_ev {
725
- self . reach ( item . owner_id . def_id , item_ev) . generics ( ) . predicates ( ) ;
733
+ self . reach ( owner_id. def_id , item_ev) . generics ( ) . predicates ( ) ;
726
734
}
727
- for variant in def. variants {
735
+ let def = self . tcx . adt_def ( owner_id) ;
736
+ for variant in def. variants ( ) {
728
737
if let Some ( item_ev) = item_ev {
729
- self . update ( variant. def_id , item_ev, Level :: Reachable ) ;
738
+ self . update ( variant. def_id . expect_local ( ) , item_ev, Level :: Reachable ) ;
730
739
}
731
740
732
- if let Some ( variant_ev) = self . get ( variant. def_id ) {
733
- if let Some ( ctor_def_id) = variant. data . ctor_def_id ( ) {
734
- self . update ( ctor_def_id, variant_ev, Level :: Reachable ) ;
741
+ if let Some ( variant_ev) = self . get ( variant. def_id . expect_local ( ) ) {
742
+ if let Some ( ctor_def_id) = variant. ctor_def_id ( ) {
743
+ self . update ( ctor_def_id. expect_local ( ) , variant_ev, Level :: Reachable ) ;
735
744
}
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 {
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 {
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 {
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 {
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