about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-04-10 00:44:14 +0000
committerJeffrey Seyfried <jeffrey.seyfried@gmail.com>2016-04-14 04:57:33 +0000
commita0c3ce342427371c447730c56f395db888087179 (patch)
tree1c4f59ae2a57c39b16a6ca3aaa7146fe6f8da91e
parenta4196cd490deba9f5d885f6c9f335c05f1048c24 (diff)
downloadrust-a0c3ce342427371c447730c56f395db888087179.tar.gz
rust-a0c3ce342427371c447730c56f395db888087179.zip
resolve: use the `Restricted` variant of `ty::Visibility` when privacy checking
-rw-r--r--src/librustc_resolve/lib.rs33
-rw-r--r--src/librustc_resolve/resolve_imports.rs15
2 files changed, 18 insertions, 30 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index c1d2b0c4b43..e161a42032d 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -907,15 +907,6 @@ impl<'a> ModuleS<'a> {
             _ => false,
         }
     }
-
-    fn is_ancestor_of(&self, module: Module<'a>) -> bool {
-        if self.def_id() == module.def_id() { return true }
-        match module.parent_link {
-            ParentLink::BlockParentLink(parent, _) |
-            ParentLink::ModuleParentLink(parent, _) => self.is_ancestor_of(parent),
-            _ => false,
-        }
-    }
 }
 
 impl<'a> fmt::Debug for ModuleS<'a> {
@@ -1330,7 +1321,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     // Check to see whether there are type bindings, and, if
                     // so, whether there is a module within.
                     if let Some(module_def) = binding.module() {
-                        self.check_privacy(search_module, name, binding, span);
+                        self.check_privacy(name, binding, span);
                         search_module = module_def;
                     } else {
                         let msg = format!("Not a module `{}`", name);
@@ -1461,7 +1452,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
     }
 
     /// Returns the nearest normal module parent of the given module.
-    fn get_nearest_normal_module_parent(&mut self, module_: Module<'a>) -> Option<Module<'a>> {
+    fn get_nearest_normal_module_parent(&self, module_: Module<'a>) -> Option<Module<'a>> {
         let mut module_ = module_;
         loop {
             match module_.parent_link {
@@ -1480,7 +1471,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
     /// Returns the nearest normal module parent of the given module, or the
     /// module itself if it is a normal module.
-    fn get_nearest_normal_module_parent_or_self(&mut self, module_: Module<'a>) -> Module<'a> {
+    fn get_nearest_normal_module_parent_or_self(&self, module_: Module<'a>) -> Module<'a> {
         if module_.is_normal() {
             return module_;
         }
@@ -2768,7 +2759,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let name = segments.last().unwrap().identifier.name;
         let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
         result.success().map(|binding| {
-            self.check_privacy(containing_module, name, binding, span);
+            self.check_privacy(name, binding, span);
             binding.def().unwrap()
         }).ok_or(false)
     }
@@ -2818,7 +2809,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let name = segments.last().unwrap().identifier.name;
         let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
         result.success().map(|binding| {
-            self.check_privacy(containing_module, name, binding, span);
+            self.check_privacy(name, binding, span);
             binding.def().unwrap()
         }).ok_or(false)
     }
@@ -3412,16 +3403,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         vis
     }
 
-    fn is_visible(&self, binding: &'a NameBinding<'a>, parent: Module<'a>) -> bool {
-        binding.is_public() || parent.is_ancestor_of(self.current_module)
+    fn is_accessible(&self, vis: ty::Visibility) -> bool {
+        let current_module = self.get_nearest_normal_module_parent_or_self(self.current_module);
+        let node_id = self.ast_map.as_local_node_id(current_module.def_id().unwrap()).unwrap();
+        vis.is_accessible_from(node_id, &self.ast_map)
     }
 
-    fn check_privacy(&mut self,
-                     module: Module<'a>,
-                     name: Name,
-                     binding: &'a NameBinding<'a>,
-                     span: Span) {
-        if !self.is_visible(binding, module) {
+    fn check_privacy(&mut self, name: Name, binding: &'a NameBinding<'a>, span: Span) {
+        if !self.is_accessible(binding.vis) {
             self.privacy_errors.push(PrivacyError(span, name, binding));
         }
     }
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index c22004910c6..31d1c570026 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -521,7 +521,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                     span_err!(self.resolver.session, directive.span, E0253, "{}", &msg);
                 }
 
-                let privacy_error = if !self.resolver.is_visible(binding, target_module) {
+                let privacy_error = if !self.resolver.is_accessible(binding.vis) {
                     Some(Box::new(PrivacyError(directive.span, source, binding)))
                 } else {
                     None
@@ -567,10 +567,10 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
             _ => (),
         }
 
+        let ast_map = self.resolver.ast_map;
         match (&value_result, &type_result) {
-            (&Success(name_binding), _) if !name_binding.is_import() &&
-                                           directive.vis == ty::Visibility::Public &&
-                                           !name_binding.is_public() => {
+            (&Success(binding), _) if !binding.vis.is_at_least(directive.vis, ast_map) &&
+                                      self.resolver.is_accessible(binding.vis) => {
                 let msg = format!("`{}` is private, and cannot be reexported", source);
                 let note_msg = format!("consider marking `{}` as `pub` in the imported module",
                                         source);
@@ -579,10 +579,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
                     .emit();
             }
 
-            (_, &Success(name_binding)) if !name_binding.is_import() &&
-                                           directive.vis == ty::Visibility::Public &&
-                                           !name_binding.is_public() => {
-                if name_binding.is_extern_crate() {
+            (_, &Success(binding)) if !binding.vis.is_at_least(directive.vis, ast_map) &&
+                                      self.resolver.is_accessible(binding.vis) => {
+                if binding.is_extern_crate() {
                     let msg = format!("extern crate `{}` is private, and cannot be reexported \
                                        (error E0364), consider declaring with `pub`",
                                        source);