about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/middle/privacy.rs6
-rw-r--r--compiler/rustc_privacy/src/lib.rs1
-rw-r--r--compiler/rustc_resolve/src/effective_visibilities.rs70
-rw-r--r--tests/ui/privacy/effective_visibilities.rs1
-rw-r--r--tests/ui/privacy/effective_visibilities.stderr60
5 files changed, 72 insertions, 66 deletions
diff --git a/compiler/rustc_middle/src/middle/privacy.rs b/compiler/rustc_middle/src/middle/privacy.rs
index 171cf1c1ab1..967fed687b6 100644
--- a/compiler/rustc_middle/src/middle/privacy.rs
+++ b/compiler/rustc_middle/src/middle/privacy.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 use rustc_macros::HashStable;
 use rustc_query_system::ich::StableHashingContext;
-use rustc_span::def_id::LocalDefId;
+use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID};
 use std::hash::Hash;
 
 /// Represents the levels of effective visibility an item can have.
@@ -107,6 +107,10 @@ impl EffectiveVisibilities {
         })
     }
 
+    pub fn update_root(&mut self) {
+        self.map.insert(CRATE_DEF_ID, EffectiveVisibility::from_vis(Visibility::Public));
+    }
+
     // FIXME: Share code with `fn update`.
     pub fn update_eff_vis(
         &mut self,
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 3be0160d561..51a0a3e9a19 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -2149,6 +2149,7 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
 
     let mut check_visitor =
         TestReachabilityVisitor { tcx, effective_visibilities: &visitor.effective_visibilities };
+    check_visitor.effective_visibility_diagnostic(CRATE_DEF_ID);
     tcx.hir().visit_all_item_likes_in_crate(&mut check_visitor);
 
     tcx.arena.alloc(visitor.effective_visibilities)
diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs
index a1ae9b8a521..3673f603d16 100644
--- a/compiler/rustc_resolve/src/effective_visibilities.rs
+++ b/compiler/rustc_resolve/src/effective_visibilities.rs
@@ -61,7 +61,7 @@ impl Resolver<'_, '_> {
         // For mod items `nearest_normal_mod` returns its argument, but we actually need its parent.
         let normal_mod_id = self.nearest_normal_mod(def_id);
         if normal_mod_id == def_id {
-            self.tcx.opt_local_parent(def_id).map_or(Visibility::Public, Visibility::Restricted)
+            Visibility::Restricted(self.tcx.local_parent(def_id))
         } else {
             Visibility::Restricted(normal_mod_id)
         }
@@ -80,12 +80,11 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
             r,
             def_effective_visibilities: Default::default(),
             import_effective_visibilities: Default::default(),
-            current_private_vis: Visibility::Public,
+            current_private_vis: Visibility::Restricted(CRATE_DEF_ID),
             changed: false,
         };
 
-        visitor.update(CRATE_DEF_ID, CRATE_DEF_ID);
-        visitor.current_private_vis = Visibility::Restricted(CRATE_DEF_ID);
+        visitor.def_effective_visibilities.update_root();
         visitor.set_bindings_effective_visibilities(CRATE_DEF_ID);
 
         while visitor.changed {
@@ -125,43 +124,32 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
 
         for (_, name_resolution) in resolutions.borrow().iter() {
             if let Some(mut binding) = name_resolution.borrow().binding() {
-                if !binding.is_ambiguity() {
-                    // Set the given effective visibility level to `Level::Direct` and
-                    // sets the rest of the `use` chain to `Level::Reexported` until
-                    // we hit the actual exported item.
-                    let mut parent_id = ParentId::Def(module_id);
-                    while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind
-                    {
-                        let binding_id = ImportId::new_unchecked(binding);
-                        self.update_import(binding_id, parent_id);
-
-                        parent_id = ParentId::Import(binding_id);
-                        binding = nested_binding;
-                    }
-
-                    if let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
-                        self.update_def(def_id, binding.vis.expect_local(), parent_id);
+                // Set the given effective visibility level to `Level::Direct` and
+                // sets the rest of the `use` chain to `Level::Reexported` until
+                // we hit the actual exported item.
+                //
+                // If the binding is ambiguous, put the root ambiguity binding and all reexports
+                // leading to it into the table. They are used by the `ambiguous_glob_reexports`
+                // lint. For all bindings added to the table this way `is_ambiguity` returns true.
+                let mut parent_id = ParentId::Def(module_id);
+                while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind {
+                    let binding_id = ImportId::new_unchecked(binding);
+                    self.update_import(binding_id, parent_id);
+
+                    if binding.ambiguity.is_some() {
+                        // Stop at the root ambiguity, further bindings in the chain should not
+                        // be reexported because the root ambiguity blocks any access to them.
+                        // (Those further bindings are most likely not ambiguities themselves.)
+                        break;
                     }
-                } else {
-                    // Put the root ambiguity binding and all reexports leading to it into the
-                    // table. They are used by the `ambiguous_glob_reexports` lint. For all
-                    // bindings added to the table here `is_ambiguity` returns true.
-                    let mut parent_id = ParentId::Def(module_id);
-                    while let NameBindingKind::Import { binding: nested_binding, .. } = binding.kind
-                    {
-                        let binding_id = ImportId::new_unchecked(binding);
-                        self.update_import(binding_id, parent_id);
 
-                        if binding.ambiguity.is_some() {
-                            // Stop at the root ambiguity, further bindings in the chain should not
-                            // be reexported because the root ambiguity blocks any access to them.
-                            // (Those further bindings are most likely not ambiguities themselves.)
-                            break;
-                        }
+                    parent_id = ParentId::Import(binding_id);
+                    binding = nested_binding;
+                }
 
-                        parent_id = ParentId::Import(binding_id);
-                        binding = nested_binding;
-                    }
+                if binding.ambiguity.is_none()
+                    && let Some(def_id) = binding.res().opt_def_id().and_then(|id| id.as_local()) {
+                    self.update_def(def_id, binding.vis.expect_local(), parent_id);
                 }
             }
         }
@@ -213,7 +201,7 @@ impl<'r, 'a, 'tcx> EffectiveVisibilitiesVisitor<'r, 'a, 'tcx> {
         );
     }
 
-    fn update(&mut self, def_id: LocalDefId, parent_id: LocalDefId) {
+    fn update_field(&mut self, def_id: LocalDefId, parent_id: LocalDefId) {
         self.update_def(def_id, self.r.visibilities[&def_id], ParentId::Def(parent_id));
     }
 }
@@ -245,14 +233,14 @@ impl<'r, 'ast, 'tcx> Visitor<'ast> for EffectiveVisibilitiesVisitor<'ast, 'r, 't
                 for variant in variants {
                     let variant_def_id = self.r.local_def_id(variant.id);
                     for field in variant.data.fields() {
-                        self.update(self.r.local_def_id(field.id), variant_def_id);
+                        self.update_field(self.r.local_def_id(field.id), variant_def_id);
                     }
                 }
             }
 
             ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
                 for field in def.fields() {
-                    self.update(self.r.local_def_id(field.id), def_id);
+                    self.update_field(self.r.local_def_id(field.id), def_id);
                 }
             }
 
diff --git a/tests/ui/privacy/effective_visibilities.rs b/tests/ui/privacy/effective_visibilities.rs
index ff20e20d332..3e9eef46230 100644
--- a/tests/ui/privacy/effective_visibilities.rs
+++ b/tests/ui/privacy/effective_visibilities.rs
@@ -1,3 +1,4 @@
+#![rustc_effective_visibility] //~ ERROR Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
 #![feature(rustc_attrs)]
 
 #[rustc_effective_visibility]
diff --git a/tests/ui/privacy/effective_visibilities.stderr b/tests/ui/privacy/effective_visibilities.stderr
index 046b6095f4e..2618fc427e9 100644
--- a/tests/ui/privacy/effective_visibilities.stderr
+++ b/tests/ui/privacy/effective_visibilities.stderr
@@ -1,140 +1,152 @@
+error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
+  --> $DIR/effective_visibilities.rs:1:1
+   |
+LL | / #![rustc_effective_visibility]
+LL | | #![feature(rustc_attrs)]
+LL | |
+LL | | #[rustc_effective_visibility]
+...  |
+LL | |
+LL | | fn main() {}
+   | |____________^
+
 error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
-  --> $DIR/effective_visibilities.rs:4:1
+  --> $DIR/effective_visibilities.rs:5:1
    |
 LL | mod outer {
    | ^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:6:5
+  --> $DIR/effective_visibilities.rs:7:5
    |
 LL |     pub mod inner1 {
    |     ^^^^^^^^^^^^^^
 
 error: not in the table
-  --> $DIR/effective_visibilities.rs:9:9
+  --> $DIR/effective_visibilities.rs:10:9
    |
 LL |         extern "C" {}
    |         ^^^^^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:12:9
+  --> $DIR/effective_visibilities.rs:13:9
    |
 LL |         pub trait PubTrait {
    |         ^^^^^^^^^^^^^^^^^^
 
 error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
-  --> $DIR/effective_visibilities.rs:20:9
+  --> $DIR/effective_visibilities.rs:21:9
    |
 LL |         struct PrivStruct;
    |         ^^^^^^^^^^^^^^^^^
 
 error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
-  --> $DIR/effective_visibilities.rs:20:9
+  --> $DIR/effective_visibilities.rs:21:9
    |
 LL |         struct PrivStruct;
    |         ^^^^^^^^^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:24:9
+  --> $DIR/effective_visibilities.rs:25:9
    |
 LL |         pub union PubUnion {
    |         ^^^^^^^^^^^^^^^^^^
 
 error: Direct: pub(self), Reexported: pub(self), Reachable: pub(self), ReachableThroughImplTrait: pub(self)
-  --> $DIR/effective_visibilities.rs:26:13
+  --> $DIR/effective_visibilities.rs:27:13
    |
 LL |             a: u8,
    |             ^^^^^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:28:13
+  --> $DIR/effective_visibilities.rs:29:13
    |
 LL |             pub b: u8,
    |             ^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:32:9
+  --> $DIR/effective_visibilities.rs:33:9
    |
 LL |         pub enum Enum {
    |         ^^^^^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:34:13
+  --> $DIR/effective_visibilities.rs:35:13
    |
 LL |             A(
    |             ^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:34:13
+  --> $DIR/effective_visibilities.rs:35:13
    |
 LL |             A(
    |             ^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:37:17
+  --> $DIR/effective_visibilities.rs:38:17
    |
 LL |                 PubUnion,
    |                 ^^^^^^^^
 
 error: not in the table
-  --> $DIR/effective_visibilities.rs:43:5
+  --> $DIR/effective_visibilities.rs:44:5
    |
 LL |     macro_rules! none_macro {
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Direct: pub(self), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:49:5
+  --> $DIR/effective_visibilities.rs:50:5
    |
 LL |     macro_rules! public_macro {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:54:5
+  --> $DIR/effective_visibilities.rs:55:5
    |
 LL |     pub struct ReachableStruct {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:56:9
+  --> $DIR/effective_visibilities.rs:57:9
    |
 LL |         pub a: u8,
    |         ^^^^^^^^^
 
 error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:61:9
+  --> $DIR/effective_visibilities.rs:62:9
    |
 LL | pub use outer::inner1;
    |         ^^^^^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:67:5
+  --> $DIR/effective_visibilities.rs:68:5
    |
 LL |     pub type HalfPublicImport = u8;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub(crate), Reachable: pub(crate), ReachableThroughImplTrait: pub(crate)
-  --> $DIR/effective_visibilities.rs:70:5
+  --> $DIR/effective_visibilities.rs:71:5
    |
 LL |     pub(crate) const HalfPublicImport: u8 = 0;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Direct: pub, Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:74:9
+  --> $DIR/effective_visibilities.rs:75:9
    |
 LL | pub use half_public_import::HalfPublicImport;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:14:13
+  --> $DIR/effective_visibilities.rs:15:13
    |
 LL |             const A: i32;
    |             ^^^^^^^^^^^^
 
 error: Direct: pub(crate), Reexported: pub, Reachable: pub, ReachableThroughImplTrait: pub
-  --> $DIR/effective_visibilities.rs:16:13
+  --> $DIR/effective_visibilities.rs:17:13
    |
 LL |             type B;
    |             ^^^^^^
 
-error: aborting due to 23 previous errors
+error: aborting due to 24 previous errors