diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2013-02-27 11:20:50 -0800 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2013-02-28 11:32:26 -0800 |
| commit | 09a2b4e5992a0508c6ea91c030ccee11151f67ac (patch) | |
| tree | 1f2ef67e3def0f64226cc3220a0534bda13d425b | |
| parent | 107bf96ff0dcc427c1842ffb232d29afaea53ca5 (diff) | |
| download | rust-09a2b4e5992a0508c6ea91c030ccee11151f67ac.tar.gz rust-09a2b4e5992a0508c6ea91c030ccee11151f67ac.zip | |
librustc: Make methods private if the impl is private
| -rw-r--r-- | src/libcore/dvec.rs | 23 | ||||
| -rw-r--r-- | src/librustc/middle/privacy.rs | 38 | ||||
| -rw-r--r-- | src/test/compile-fail/private-method-inherited.rs | 15 |
3 files changed, 63 insertions, 13 deletions
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 @@ -93,17 +93,6 @@ priv impl<A> DVec<A> { } #[inline(always)] - fn check_out<B>(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 { self.data = data; @@ -118,6 +107,18 @@ priv impl<A> DVec<A> { // almost nothing works without the copy bound due to limitations // around closures. pub impl<A> DVec<A> { + // FIXME (#3758): This should not need to be public. + #[inline(always)] + fn check_out<B>(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 +} + |
