about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2015-03-15 18:47:00 +1300
committerNick Cameron <ncameron@mozilla.com>2015-03-16 11:03:54 +1300
commit170ccd615f976fc9e90a8f14ce6c373bfdf01533 (patch)
tree5a52a42204b6cc769bd2761b438f1e9a55060b20
parent73afbef3aaf42288a766186628207d46fbde1ee0 (diff)
downloadrust-170ccd615f976fc9e90a8f14ce6c373bfdf01533.tar.gz
rust-170ccd615f976fc9e90a8f14ce6c373bfdf01533.zip
Error if `pub use` references a private item.
[breaking-change]

Closes #23266
-rw-r--r--src/librustc_resolve/diagnostics.rs4
-rw-r--r--src/librustc_resolve/lib.rs32
2 files changed, 31 insertions, 5 deletions
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index 124aa392435..c586faae6e8 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -24,7 +24,9 @@ register_diagnostics! {
     E0258, // import conflicts with existing submodule
     E0259, // an extern crate has already been imported into this module
     E0260, // name conflicts with an external crate that has been imported into this module
-    E0317 // user-defined types or type parameters cannot shadow the primitive types
+    E0317, // user-defined types or type parameters cannot shadow the primitive types
+    E0364, // item is private
+    E0365  // item is private
 }
 
 __build_diagnostic_array! { DIAGNOSTICS }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 60538575404..cf974024e8b 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -857,6 +857,19 @@ impl NameBindings {
             None
         }
     }
+
+    fn is_public(&self, namespace: Namespace) -> bool {
+        match namespace {
+            TypeNS  => {
+                let type_def = self.type_def.borrow();
+                type_def.as_ref().unwrap().modifiers.contains(PUBLIC)
+            }
+            ValueNS => {
+                let value_def = self.value_def.borrow();
+                value_def.as_ref().unwrap().modifiers.contains(PUBLIC)
+            }
+        }
+    }
 }
 
 /// Interns the names of the primitive types.
@@ -1334,22 +1347,33 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let mut type_result = UnknownResult;
 
         // Search for direct children of the containing module.
-        build_reduced_graph::populate_module_if_necessary(self, &containing_module);
+        build_reduced_graph::populate_module_if_necessary(self, &target_module);
 
-        match containing_module.children.borrow().get(&source) {
+        match target_module.children.borrow().get(&source) {
             None => {
                 // Continue.
             }
             Some(ref child_name_bindings) => {
+                // pub_err makes sure we don't give the same error twice.
+                let mut pub_err = false;
                 if child_name_bindings.defined_in_namespace(ValueNS) {
                     debug!("(resolving single import) found value binding");
-                    value_result = BoundResult(containing_module.clone(),
+                    value_result = BoundResult(target_module.clone(),
                                                (*child_name_bindings).clone());
+                    if directive.is_public && !child_name_bindings.is_public(ValueNS) {
+                        let msg = format!("`{}` is private", token::get_name(source));
+                        span_err!(self.session, directive.span, E0364, "{}", &msg);
+                        pub_err = true;
+                    }
                 }
                 if child_name_bindings.defined_in_namespace(TypeNS) {
                     debug!("(resolving single import) found type binding");
-                    type_result = BoundResult(containing_module.clone(),
+                    type_result = BoundResult(target_module.clone(),
                                               (*child_name_bindings).clone());
+                    if !pub_err && directive.is_public && !child_name_bindings.is_public(TypeNS) {
+                        let msg = format!("`{}` is private", token::get_name(source));
+                        span_err!(self.session, directive.span, E0365, "{}", &msg);
+                    }
                 }
             }
         }