Enable privacy check for enum methods.

This commit is contained in:
Michael Woerister 2013-08-07 14:29:29 +02:00
parent 4da1cfe923
commit 2c9922aa49
5 changed files with 59 additions and 26 deletions

View file

@ -403,6 +403,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
// Ditto // Ditto
match ty::get(ty::type_autoderef(tcx, ty::expr_ty(tcx, match ty::get(ty::type_autoderef(tcx, ty::expr_ty(tcx,
base))).sty { base))).sty {
ty_enum(id, _) |
ty_struct(id, _) ty_struct(id, _)
if id.crate != LOCAL_CRATE || if id.crate != LOCAL_CRATE ||
!privileged_items.iter().any(|x| x == &(id.node)) => { !privileged_items.iter().any(|x| x == &(id.node)) => {

View file

@ -417,12 +417,12 @@ pub enum MapChain<K,V> {
// get the map from an env frame // get the map from an env frame
impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{
// Constructor. I don't think we need a zero-arg one. // Constructor. I don't think we need a zero-arg one.
fn new(init: ~HashMap<K,@V>) -> @mut MapChain<K,V> { pub fn new(init: ~HashMap<K,@V>) -> @mut MapChain<K,V> {
@mut BaseMapChain(init) @mut BaseMapChain(init)
} }
// add a new frame to the environment (functionally) // add a new frame to the environment (functionally)
fn push_frame (@mut self) -> @mut MapChain<K,V> { pub fn push_frame (@mut self) -> @mut MapChain<K,V> {
@mut ConsMapChain(~HashMap::new() ,self) @mut ConsMapChain(~HashMap::new() ,self)
} }
@ -432,7 +432,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{
// ugh: can't get this to compile with mut because of the // ugh: can't get this to compile with mut because of the
// lack of flow sensitivity. // lack of flow sensitivity.
fn get_map<'a>(&'a self) -> &'a HashMap<K,@V> { pub fn get_map<'a>(&'a self) -> &'a HashMap<K,@V> {
match *self { match *self {
BaseMapChain (~ref map) => map, BaseMapChain (~ref map) => map,
ConsMapChain (~ref map,_) => map ConsMapChain (~ref map,_) => map
@ -442,7 +442,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{
// traits just don't work anywhere...? // traits just don't work anywhere...?
//impl Map<Name,SyntaxExtension> for MapChain { //impl Map<Name,SyntaxExtension> for MapChain {
fn contains_key (&self, key: &K) -> bool { pub fn contains_key (&self, key: &K) -> bool {
match *self { match *self {
BaseMapChain (ref map) => map.contains_key(key), BaseMapChain (ref map) => map.contains_key(key),
ConsMapChain (ref map,ref rest) => ConsMapChain (ref map,ref rest) =>
@ -453,17 +453,17 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{
// should each_key and each_value operate on shadowed // should each_key and each_value operate on shadowed
// names? I think not. // names? I think not.
// delaying implementing this.... // delaying implementing this....
fn each_key (&self, _f: &fn (&K)->bool) { pub fn each_key (&self, _f: &fn (&K)->bool) {
fail!("unimplemented 2013-02-15T10:01"); fail!("unimplemented 2013-02-15T10:01");
} }
fn each_value (&self, _f: &fn (&V) -> bool) { pub fn each_value (&self, _f: &fn (&V) -> bool) {
fail!("unimplemented 2013-02-15T10:02"); fail!("unimplemented 2013-02-15T10:02");
} }
// Returns a copy of the value that the name maps to. // Returns a copy of the value that the name maps to.
// Goes down the chain 'til it finds one (or bottom out). // Goes down the chain 'til it finds one (or bottom out).
fn find (&self, key: &K) -> Option<@V> { pub fn find (&self, key: &K) -> Option<@V> {
match self.get_map().find (key) { match self.get_map().find (key) {
Some(ref v) => Some(**v), Some(ref v) => Some(**v),
None => match *self { None => match *self {
@ -473,7 +473,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{
} }
} }
fn find_in_topmost_frame(&self, key: &K) -> Option<@V> { pub fn find_in_topmost_frame(&self, key: &K) -> Option<@V> {
let map = match *self { let map = match *self {
BaseMapChain(ref map) => map, BaseMapChain(ref map) => map,
ConsMapChain(ref map,_) => map ConsMapChain(ref map,_) => map
@ -483,7 +483,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{
} }
// insert the binding into the top-level map // insert the binding into the top-level map
fn insert (&mut self, key: K, ext: @V) -> bool { pub fn insert (&mut self, key: K, ext: @V) -> bool {
// can't abstract over get_map because of flow sensitivity... // can't abstract over get_map because of flow sensitivity...
match *self { match *self {
BaseMapChain (~ref mut map) => map.insert(key, ext), BaseMapChain (~ref mut map) => map.insert(key, ext),
@ -495,7 +495,7 @@ impl <K: Eq + Hash + IterBytes + 'static, V: 'static> MapChain<K,V>{
// ... there are definitely some opportunities for abstraction // ... there are definitely some opportunities for abstraction
// here that I'm ignoring. (e.g., manufacturing a predicate on // here that I'm ignoring. (e.g., manufacturing a predicate on
// the maps in the chain, and using an abstract "find". // the maps in the chain, and using an abstract "find".
fn insert_into_frame(&mut self, key: K, ext: @V, n: K, pred: &fn(&@V)->bool) { pub fn insert_into_frame(&mut self, key: K, ext: @V, n: K, pred: &fn(&@V)->bool) {
match *self { match *self {
BaseMapChain (~ref mut map) => { BaseMapChain (~ref mut map) => {
if satisfies_pred(map,&n,pred) { if satisfies_pred(map,&n,pred) {

View file

@ -36,7 +36,7 @@ pub fn from<T>(t: ~[T]) -> OptVec<T> {
} }
impl<T> OptVec<T> { impl<T> OptVec<T> {
fn push(&mut self, t: T) { pub fn push(&mut self, t: T) {
match *self { match *self {
Vec(ref mut v) => { Vec(ref mut v) => {
v.push(t); v.push(t);
@ -50,32 +50,32 @@ impl<T> OptVec<T> {
*self = Vec(~[t]); *self = Vec(~[t]);
} }
fn map<U>(&self, op: &fn(&T) -> U) -> OptVec<U> { pub fn map<U>(&self, op: &fn(&T) -> U) -> OptVec<U> {
match *self { match *self {
Empty => Empty, Empty => Empty,
Vec(ref v) => Vec(v.map(op)) Vec(ref v) => Vec(v.map(op))
} }
} }
fn map_consume<U>(self, op: &fn(T) -> U) -> OptVec<U> { pub fn map_consume<U>(self, op: &fn(T) -> U) -> OptVec<U> {
match self { match self {
Empty => Empty, Empty => Empty,
Vec(v) => Vec(v.consume_iter().transform(op).collect()) Vec(v) => Vec(v.consume_iter().transform(op).collect())
} }
} }
fn get<'a>(&'a self, i: uint) -> &'a T { pub fn get<'a>(&'a self, i: uint) -> &'a T {
match *self { match *self {
Empty => fail!("Invalid index %u", i), Empty => fail!("Invalid index %u", i),
Vec(ref v) => &v[i] Vec(ref v) => &v[i]
} }
} }
fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
self.len() == 0 self.len() == 0
} }
fn len(&self) -> uint { pub fn len(&self) -> uint {
match *self { match *self {
Empty => 0, Empty => 0,
Vec(ref v) => v.len() Vec(ref v) => v.len()
@ -83,7 +83,7 @@ impl<T> OptVec<T> {
} }
#[inline] #[inline]
fn iter<'r>(&'r self) -> OptVecIterator<'r, T> { pub fn iter<'r>(&'r self) -> OptVecIterator<'r, T> {
match *self { match *self {
Empty => OptVecIterator{iter: None}, Empty => OptVecIterator{iter: None},
Vec(ref v) => OptVecIterator{iter: Some(v.iter())} Vec(ref v) => OptVecIterator{iter: Some(v.iter())}
@ -91,11 +91,11 @@ impl<T> OptVec<T> {
} }
#[inline] #[inline]
fn map_to_vec<B>(&self, op: &fn(&T) -> B) -> ~[B] { pub fn map_to_vec<B>(&self, op: &fn(&T) -> B) -> ~[B] {
self.iter().transform(op).collect() self.iter().transform(op).collect()
} }
fn mapi_to_vec<B>(&self, op: &fn(uint, &T) -> B) -> ~[B] { pub fn mapi_to_vec<B>(&self, op: &fn(uint, &T) -> B) -> ~[B] {
let mut index = 0; let mut index = 0;
self.map_to_vec(|a| { self.map_to_vec(|a| {
let i = index; let i = index;
@ -113,7 +113,7 @@ pub fn take_vec<T>(v: OptVec<T>) -> ~[T] {
} }
impl<T:Clone> OptVec<T> { impl<T:Clone> OptVec<T> {
fn prepend(&self, t: T) -> OptVec<T> { pub fn prepend(&self, t: T) -> OptVec<T> {
let mut v0 = ~[t]; let mut v0 = ~[t];
match *self { match *self {
Empty => {} Empty => {}
@ -124,7 +124,7 @@ impl<T:Clone> OptVec<T> {
} }
impl<A:Eq> Eq for OptVec<A> { impl<A:Eq> Eq for OptVec<A> {
fn eq(&self, other: &OptVec<A>) -> bool { pub fn eq(&self, other: &OptVec<A>) -> bool {
// Note: cannot use #[deriving(Eq)] here because // Note: cannot use #[deriving(Eq)] here because
// (Empty, Vec(~[])) ought to be equal. // (Empty, Vec(~[])) ought to be equal.
match (self, other) { match (self, other) {
@ -135,7 +135,7 @@ impl<A:Eq> Eq for OptVec<A> {
} }
} }
fn ne(&self, other: &OptVec<A>) -> bool { pub fn ne(&self, other: &OptVec<A>) -> bool {
!self.eq(other) !self.eq(other)
} }
} }

View file

@ -1,9 +1,33 @@
#[crate_type="lib"]; #[crate_type="lib"];
pub struct Foo { pub struct Struct {
x: int x: int
} }
impl Foo { impl Struct {
fn new() -> Foo { Foo { x: 1 } } fn static_meth_struct() -> Struct {
Struct { x: 1 }
}
fn meth_struct(&self) -> int {
self.x
}
}
pub enum Enum {
Variant1(int),
Variant2(int)
}
impl Enum {
fn static_meth_enum() -> Enum {
Variant2(10)
}
fn meth_enum(&self) -> int {
match *self {
Variant1(x) |
Variant2(x) => x
}
}
} }

View file

@ -4,5 +4,13 @@
extern mod xc_private_method_lib; extern mod xc_private_method_lib;
fn main() { fn main() {
let _ = xc_private_method_lib::Foo::new(); //~ ERROR function `new` is private // normal method on struct
let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct(); //~ ERROR method `meth_struct` is private
// static method on struct
let _ = xc_private_method_lib::Struct::static_meth_struct(); //~ ERROR function `static_meth_struct` is private
// normal method on enum
let _ = xc_private_method_lib::Variant1(20).meth_enum(); //~ ERROR method `meth_enum` is private
// static method on enum
let _ = xc_private_method_lib::Enum::static_meth_enum(); //~ ERROR function `static_meth_enum` is private
} }