about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-03-21 10:07:22 -0700
committerbors <bors@rust-lang.org>2013-03-21 10:07:22 -0700
commit87d9316793d2bd1313ebf51c46bd02f06227044c (patch)
treee0a44f88291d3db7eb9582a39aa5f2dadc37ee75
parent56d288d0dc89ae8d284ffddf74f6be9d0f37362e (diff)
parent5726fd45268d1ef3574c9321c7ce6efb7e676eac (diff)
downloadrust-87d9316793d2bd1313ebf51c46bd02f06227044c.tar.gz
rust-87d9316793d2bd1313ebf51c46bd02f06227044c.zip
auto merge of #5457 : pcwalton/rust/xcpsm, r=pcwalton
r? @catamorphism
-rw-r--r--src/librustc/metadata/csearch.rs8
-rw-r--r--src/librustc/metadata/decoder.rs21
-rw-r--r--src/librustc/middle/privacy.rs15
-rw-r--r--src/test/auxiliary/xc_private_method_lib.rs10
-rw-r--r--src/test/compile-fail/xc-private-method.rs9
5 files changed, 46 insertions, 17 deletions
diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 47ee477210b..16b896f11d6 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -229,11 +229,11 @@ pub fn struct_dtor(cstore: @mut cstore::CStore, def: ast::def_id)
     decoder::struct_dtor(cdata, def.node)
 }
 
-pub fn get_method_visibility(cstore: @mut cstore::CStore,
-                             def_id: ast::def_id)
-                          -> ast::visibility {
+pub fn get_item_visibility(cstore: @mut cstore::CStore,
+                           def_id: ast::def_id)
+                        -> ast::visibility {
     let cdata = cstore::get_crate_data(cstore, def_id.crate);
-    decoder::get_method_visibility(cdata, def_id.node)
+    decoder::get_item_visibility(cdata, def_id.node)
 }
 
 pub fn get_link_args_for_crate(cstore: @mut cstore::CStore,
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index c4644a61164..292a1106261 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -145,13 +145,16 @@ fn item_family(item: ebml::Doc) -> Family {
 }
 
 fn item_visibility(item: ebml::Doc) -> ast::visibility {
-    let visibility = reader::get_doc(item, tag_items_data_item_visibility);
-    debug!("item visibility for %?", item_family(item));
-    match reader::doc_as_u8(visibility) as char {
-        'y' => ast::public,
-        'n' => ast::private,
-        'i' => ast::inherited,
-        _ => fail!(~"unknown visibility character"),
+    match reader::maybe_get_doc(item, tag_items_data_item_visibility) {
+        None => ast::public,
+        Some(visibility_doc) => {
+            match reader::doc_as_u8(visibility_doc) as char {
+                'y' => ast::public,
+                'n' => ast::private,
+                'i' => ast::inherited,
+                _ => fail!(~"unknown visibility character")
+            }
+        }
     }
 }
 
@@ -909,8 +912,8 @@ pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id)
     result
 }
 
-pub fn get_method_visibility(cdata: cmd, id: ast::node_id)
-                          -> ast::visibility {
+pub fn get_item_visibility(cdata: cmd, id: ast::node_id)
+                        -> ast::visibility {
     item_visibility(lookup_item(id, cdata.data))
 }
 
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 5a4fe4018ce..c3a65a4f256 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -265,8 +265,7 @@ pub fn check_crate(tcx: ty::ctxt,
             }
         } else {
             let visibility =
-                csearch::get_method_visibility(tcx.sess.cstore,
-                                               method_id);
+                csearch::get_item_visibility(tcx.sess.cstore, method_id);
             if visibility != public {
                 tcx.sess.span_err(span,
                                   fmt!("method `%s` is private",
@@ -298,8 +297,16 @@ pub fn check_crate(tcx: ty::ctxt,
                                                              .idents
                                                              .last())));
                     }
-                } else {
-                    // XXX: Check privacy in external crates.
+                } else if csearch::get_item_visibility(tcx.sess.cstore,
+                                                       def_id) != public {
+                    tcx.sess.span_err(span,
+                                      fmt!("function `%s` is private",
+                                           *tcx.sess
+                                               .parse_sess
+                                               .interner
+                                               .get(copy *path
+                                                         .idents
+                                                         .last())));
                 }
             }
             _ => {}
diff --git a/src/test/auxiliary/xc_private_method_lib.rs b/src/test/auxiliary/xc_private_method_lib.rs
new file mode 100644
index 00000000000..f9fda2b0810
--- /dev/null
+++ b/src/test/auxiliary/xc_private_method_lib.rs
@@ -0,0 +1,10 @@
+#[crate_type="lib"];
+
+pub struct Foo {
+    x: int
+}
+
+impl Foo {
+    fn new() -> Foo { Foo { x: 1 } }
+}
+
diff --git a/src/test/compile-fail/xc-private-method.rs b/src/test/compile-fail/xc-private-method.rs
new file mode 100644
index 00000000000..d194820df94
--- /dev/null
+++ b/src/test/compile-fail/xc-private-method.rs
@@ -0,0 +1,9 @@
+// xfail-fast
+// aux-build:xc_private_method_lib.rs
+
+extern mod xc_private_method_lib;
+
+fn main() {
+    let _ = xc_private_method_lib::Foo::new();  //~ ERROR function `new` is private
+}
+