]> git.lizzy.rs Git - rust.git/commitdiff
Split up privacy checking so privacy_access_levels only does computations required...
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Sat, 23 Feb 2019 15:40:15 +0000 (16:40 +0100)
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>
Wed, 6 Mar 2019 03:47:03 +0000 (04:47 +0100)
src/librustc/dep_graph/dep_node.rs
src/librustc/ty/query/config.rs
src/librustc/ty/query/mod.rs
src/librustc/ty/query/plumbing.rs
src/librustc_interface/passes.rs
src/librustc_privacy/lib.rs
src/test/ui/privacy/private-inferred-type.stderr

index c607eb5906e605122d54f9aa51523a534930c58e..a46ffffe94cb8a7a55325442f8d9746bd477ed93 100644 (file)
@@ -456,6 +456,7 @@ pub fn to_dep_node(self, tcx: TyCtxt<'_, '_, '_>, kind: DepKind) -> DepNode {
     [eval_always] CoherenceInherentImplOverlapCheck,
     [] CoherenceCheckTrait(DefId),
     [eval_always] PrivacyAccessLevels(CrateNum),
+    [eval_always] CheckPrivacy(CrateNum),
     [eval_always] Analysis(CrateNum),
 
     // Represents the MIR for a fn; also used as the task node for
index feca0f7170ef3d11b5d7dd3444dcd01001cce48c..0fef90c945e941e0c76bbb8790cdf5d12a86a9f6 100644 (file)
@@ -369,6 +369,12 @@ fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
     }
 }
 
+impl<'tcx> QueryDescription<'tcx> for queries::check_privacy<'tcx> {
+    fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
+        "privacy checking".into()
+    }
+}
+
 impl<'tcx> QueryDescription<'tcx> for queries::typeck_item_bodies<'tcx> {
     fn describe(_: TyCtxt<'_, '_, '_>, _: CrateNum) -> Cow<'static, str> {
         "type-checking all item bodies".into()
index 197b9a71b0ac0f31b83b34a7de9a683fcfd959af..cb72ad6fe8bd9074ef76e7f9c2c0c9f571e74e70 100644 (file)
         [] fn check_match: CheckMatch(DefId)
             -> Result<(), ErrorReported>,
 
-        /// Performs the privacy check and computes "access levels".
+        /// Performs part of the privacy check and computes "access levels".
         [] fn privacy_access_levels: PrivacyAccessLevels(CrateNum) -> Lrc<AccessLevels>,
+        [] fn check_privacy: CheckPrivacy(CrateNum) -> (),
     },
 
     Other {
index ebaa31d703f8e0195fa969b8cb1364fd0b83665d..ff2639da13650d3809bb3621919b6459fd28ff74 100644 (file)
@@ -1251,6 +1251,7 @@ macro_rules! force {
             force!(crate_inherent_impls_overlap_check, LOCAL_CRATE)
         },
         DepKind::PrivacyAccessLevels => { force!(privacy_access_levels, LOCAL_CRATE); }
+        DepKind::CheckPrivacy => { force!(check_privacy, LOCAL_CRATE); }
         DepKind::MirBuilt => { force!(mir_built, def_id!()); }
         DepKind::MirConstQualif => { force!(mir_const_qualif, def_id!()); }
         DepKind::MirConst => { force!(mir_const, def_id!()); }
index 16ced6956380bc4303dacc688df7633255faa036..591583a1526d0e80d6968ad3876e1cfddcac6da7 100644 (file)
@@ -21,7 +21,7 @@
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::stable_hasher::StableHasher;
-use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::sync::{Lrc, ParallelIterator, par_iter};
 use rustc_incremental;
 use rustc_metadata::creader::CrateLoader;
 use rustc_metadata::cstore::{self, CStore};
@@ -278,17 +278,28 @@ fn analysis<'tcx>(
 
     time(sess, "misc checking", || {
         parallel!({
-            time(sess, "privacy checking", || {
-                rustc_privacy::check_crate(tcx)
+            time(sess, "privacy access levels", || {
+                tcx.ensure().privacy_access_levels(LOCAL_CRATE);
             });
-        }, {
-            time(sess, "death checking", || middle::dead::check_crate(tcx));
-        },  {
-            time(sess, "unused lib feature checking", || {
-                stability::check_unused_or_stable_features(tcx)
+            parallel!({
+                time(sess, "privacy checking", || {
+                    tcx.ensure().check_privacy(LOCAL_CRATE);
+                });
+            }, {
+                time(sess, "death checking", || middle::dead::check_crate(tcx));
+            },  {
+                time(sess, "unused lib feature checking", || {
+                    stability::check_unused_or_stable_features(tcx)
+                });
+            }, {
+                time(sess, "lint checking", || lint::check_crate(tcx));
             });
         }, {
-            time(sess, "lint checking", || lint::check_crate(tcx));
+            time(sess, "privacy checking modules", || {
+                par_iter(&tcx.hir().krate().modules).for_each(|(&module, _)| {
+                    tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module));
+                });
+            });
         });
     });
 
index 550b333700b04939b3f39cc446368bd2ca35694e..372a9230694249c446d1a0765a785e5018965124 100644 (file)
@@ -1760,19 +1760,15 @@ fn visit_item(&mut self, item: &'tcx hir::Item) {
 pub fn provide(providers: &mut Providers<'_>) {
     *providers = Providers {
         privacy_access_levels,
+        check_privacy,
         check_mod_privacy,
         ..*providers
     };
 }
 
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Lrc<AccessLevels> {
-    tcx.privacy_access_levels(LOCAL_CRATE)
-}
-
 fn check_mod_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
     let empty_tables = ty::TypeckTables::empty(None);
 
-
     // Check privacy of names not checked in previous compilation stages.
     let mut visitor = NamePrivacyVisitor {
         tcx,
@@ -1803,18 +1799,6 @@ fn privacy_access_levels<'tcx>(
 ) -> Lrc<AccessLevels> {
     assert_eq!(krate, LOCAL_CRATE);
 
-    let krate = tcx.hir().krate();
-
-    for &module in krate.modules.keys() {
-        tcx.ensure().check_mod_privacy(tcx.hir().local_def_id(module));
-    }
-
-    let private_crates: FxHashSet<CrateNum> = tcx.sess.opts.extern_private.iter()
-        .flat_map(|c| {
-            tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned()
-        }).collect();
-
-
     // Build up a set of all exported items in the AST. This is a set of all
     // items which are reachable from external crates based on visibility.
     let mut visitor = EmbargoVisitor {
@@ -1824,7 +1808,7 @@ fn privacy_access_levels<'tcx>(
         changed: false,
     };
     loop {
-        intravisit::walk_crate(&mut visitor, krate);
+        intravisit::walk_crate(&mut visitor, tcx.hir().krate());
         if visitor.changed {
             visitor.changed = false;
         } else {
@@ -1833,36 +1817,46 @@ fn privacy_access_levels<'tcx>(
     }
     visitor.update(hir::CRATE_HIR_ID, Some(AccessLevel::Public));
 
-    {
-        let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
-            tcx,
-            access_levels: &visitor.access_levels,
-            in_variant: false,
-            old_error_set: Default::default(),
-        };
-        intravisit::walk_crate(&mut visitor, krate);
+    Lrc::new(visitor.access_levels)
+}
 
+fn check_privacy<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, krate: CrateNum) {
+    assert_eq!(krate, LOCAL_CRATE);
 
-        let has_pub_restricted = {
-            let mut pub_restricted_visitor = PubRestrictedVisitor {
-                tcx,
-                has_pub_restricted: false
-            };
-            intravisit::walk_crate(&mut pub_restricted_visitor, krate);
-            pub_restricted_visitor.has_pub_restricted
-        };
+    let access_levels = tcx.privacy_access_levels(LOCAL_CRATE);
 
-        // Check for private types and traits in public interfaces.
-        let mut visitor = PrivateItemsInPublicInterfacesVisitor {
+    let krate = tcx.hir().krate();
+
+    let mut visitor = ObsoleteVisiblePrivateTypesVisitor {
+        tcx,
+        access_levels: &access_levels,
+        in_variant: false,
+        old_error_set: Default::default(),
+    };
+    intravisit::walk_crate(&mut visitor, krate);
+
+    let has_pub_restricted = {
+        let mut pub_restricted_visitor = PubRestrictedVisitor {
             tcx,
-            has_pub_restricted,
-            old_error_set: &visitor.old_error_set,
-            private_crates
+            has_pub_restricted: false
         };
-        krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
-    }
+        intravisit::walk_crate(&mut pub_restricted_visitor, krate);
+        pub_restricted_visitor.has_pub_restricted
+    };
 
-    Lrc::new(visitor.access_levels)
+    let private_crates: FxHashSet<CrateNum> = tcx.sess.opts.extern_private.iter()
+        .flat_map(|c| {
+            tcx.crates().iter().find(|&&krate| &tcx.crate_name(krate) == c).cloned()
+        }).collect();
+
+    // Check for private types and traits in public interfaces.
+    let mut visitor = PrivateItemsInPublicInterfacesVisitor {
+        tcx,
+        has_pub_restricted,
+        old_error_set: &visitor.old_error_set,
+        private_crates
+    };
+    krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
 }
 
 __build_diagnostic_array! { librustc_privacy, DIAGNOSTICS }
index 80a475f7dceea2266002e1897d0d930768aa09e0..568d4dadc8cc47e0c983ae66ccc1c08bb82b6029 100644 (file)
@@ -1,3 +1,21 @@
+error[E0446]: private type `m::Priv` in public interface
+  --> $DIR/private-inferred-type.rs:61:36
+   |
+LL |     struct Priv;
+   |     - `m::Priv` declared as private
+...
+LL |     impl TraitWithAssocTy for u8 { type AssocTy = Priv; }
+   |                                    ^^^^^^^^^^^^^^^^^^^^ can't leak private type
+
+error[E0446]: private type `adjust::S2` in public interface
+  --> $DIR/private-inferred-type.rs:83:9
+   |
+LL |     struct S2;
+   |     - `adjust::S2` declared as private
+...
+LL |         type Target = S2Alias; //~ ERROR private type `adjust::S2` in public interface
+   |         ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
+
 error: type `m::Priv` is private
   --> $DIR/private-inferred-type.rs:97:9
    |
@@ -202,24 +220,6 @@ error: type `m::Priv` is private
 LL |     match a { //~ ERROR type `m::Priv` is private
    |           ^
 
-error[E0446]: private type `m::Priv` in public interface
-  --> $DIR/private-inferred-type.rs:61:36
-   |
-LL |     struct Priv;
-   |     - `m::Priv` declared as private
-...
-LL |     impl TraitWithAssocTy for u8 { type AssocTy = Priv; }
-   |                                    ^^^^^^^^^^^^^^^^^^^^ can't leak private type
-
-error[E0446]: private type `adjust::S2` in public interface
-  --> $DIR/private-inferred-type.rs:83:9
-   |
-LL |     struct S2;
-   |     - `adjust::S2` declared as private
-...
-LL |         type Target = S2Alias; //~ ERROR private type `adjust::S2` in public interface
-   |         ^^^^^^^^^^^^^^^^^^^^^^ can't leak private type
-
 error: aborting due to 33 previous errors
 
 For more information about this error, try `rustc --explain E0446`.