From 09a2b4e5992a0508c6ea91c030ccee11151f67ac Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 27 Feb 2013 11:20:50 -0800 Subject: librustc: Make methods private if the impl is private --- src/libcore/dvec.rs | 23 +++++++------- src/librustc/middle/privacy.rs | 38 +++++++++++++++++++++-- src/test/compile-fail/private-method-inherited.rs | 15 +++++++++ 3 files changed, 63 insertions(+), 13 deletions(-) create mode 100644 src/test/compile-fail/private-method-inherited.rs (limited to 'src') diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index 6c7c195b9d3..1fef4ad42f1 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -92,17 +92,6 @@ priv impl DVec { } } - #[inline(always)] - fn check_out(f: &fn(v: ~[A]) -> B) -> B { - unsafe { - let mut data = cast::reinterpret_cast(&null::<()>()); - data <-> self.data; - let data_ptr: *() = cast::reinterpret_cast(&data); - if data_ptr.is_null() { fail!(~"Recursive use of dvec"); } - return f(data); - } - } - #[inline(always)] fn give_back(data: ~[A]) { unsafe { @@ -118,6 +107,18 @@ priv impl DVec { // almost nothing works without the copy bound due to limitations // around closures. pub impl DVec { + // FIXME (#3758): This should not need to be public. + #[inline(always)] + fn check_out(f: &fn(v: ~[A]) -> B) -> B { + unsafe { + let mut data = cast::reinterpret_cast(&null::<()>()); + data <-> self.data; + let data_ptr: *() = cast::reinterpret_cast(&data); + if data_ptr.is_null() { fail!(~"Recursive use of dvec"); } + return f(data); + } + } + /// Reserves space for N elements fn reserve(count: uint) { vec::reserve(&mut self.data, count) diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 3ec1cf3a705..712037720d5 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -25,7 +25,7 @@ use core::util::ignore; use syntax::ast::{def_variant, expr_field, expr_method_call, expr_struct}; use syntax::ast::{expr_unary, ident, item_struct, item_enum, item_impl}; use syntax::ast::{item_trait, local_crate, node_id, pat_struct, private}; -use syntax::ast::{provided, required}; +use syntax::ast::{provided, public, required}; use syntax::ast; use syntax::ast_map::{node_item, node_method}; use syntax::ast_map; @@ -107,7 +107,41 @@ pub fn check_crate(tcx: ty::ctxt, if method_id.crate == local_crate { match tcx.items.find(&method_id.node) { Some(node_method(method, impl_id, _)) => { - if method.vis == private && + let mut is_private = false; + if method.vis == private { + is_private = true; + } else { + // Look up the enclosing impl. + if impl_id.crate != local_crate { + tcx.sess.span_bug(span, + ~"local method isn't \ + in local impl?!"); + } + + match tcx.items.find(&impl_id.node) { + Some(node_item(item, _)) => { + match item.node { + item_impl(_, None, _, _) + if item.vis != public => { + is_private = true; + } + _ => {} + } + } + Some(_) => { + tcx.sess.span_bug(span, + ~"impl wasn't an \ + item?!"); + } + None => { + tcx.sess.span_bug(span, + ~"impl wasn't in \ + AST map?!"); + } + } + } + + if is_private && (impl_id.crate != local_crate || !privileged_items .contains(&(impl_id.node))) { diff --git a/src/test/compile-fail/private-method-inherited.rs b/src/test/compile-fail/private-method-inherited.rs new file mode 100644 index 00000000000..7b64623e16c --- /dev/null +++ b/src/test/compile-fail/private-method-inherited.rs @@ -0,0 +1,15 @@ +// Tests that inherited visibility applies to methods. + +mod a { + pub struct Foo; + + impl Foo { + fn f(self) {} + } +} + +fn main() { + let x = a::Foo; + x.f(); //~ ERROR method `f` is private +} + -- cgit 1.4.1-3-g733a5