diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 47ee477210b78c04cdb02eccf440dd473cb9d2d9..16b896f11d6a495a6af2dc2dd7ccac860acce110 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 c4644a611648dfc117a7098689fcbcb6a7d516c0..292a11062613d953566a392b1b208d8fe0cbf9f2 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 5a4fe4018ceaf33de04808b75b2f1859c84754c8..c3a65a4f256f447bacf082b8aedb5df4c1f4bea8 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 0000000000000000000000000000000000000000..f9fda2b0810b350624ec05b1c676428d92523d3f --- /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 0000000000000000000000000000000000000000..d194820df9408abfbfc96bb2210594439a74a8b1 --- /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 +} +