auto merge of #11777 : alexcrichton/rust/issue-11522, r=pnkfelix
See #11522, but the idea is for private structs to have private fields by default, whereas public structs will continue to have public fields by default.
This commit is contained in:
commit
6743c650c1
35 changed files with 187 additions and 83 deletions
|
@ -90,7 +90,7 @@ Reaching the end of the iterator is signalled by returning `None` instead of
|
||||||
# fn main() {}
|
# fn main() {}
|
||||||
/// A stream of N zeroes
|
/// A stream of N zeroes
|
||||||
struct ZeroStream {
|
struct ZeroStream {
|
||||||
priv remaining: uint
|
remaining: uint
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZeroStream {
|
impl ZeroStream {
|
||||||
|
@ -305,7 +305,7 @@ The `ZeroStream` from earlier can provide an exact lower and upper bound:
|
||||||
# fn main() {}
|
# fn main() {}
|
||||||
/// A stream of N zeroes
|
/// A stream of N zeroes
|
||||||
struct ZeroStream {
|
struct ZeroStream {
|
||||||
priv remaining: uint
|
remaining: uint
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZeroStream {
|
impl ZeroStream {
|
||||||
|
|
|
@ -148,7 +148,7 @@ impl<T:Freeze + Send> Clone for Arc<T> {
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
struct MutexArcInner<T> { priv lock: Mutex, priv failed: bool, priv data: T }
|
struct MutexArcInner<T> { lock: Mutex, failed: bool, data: T }
|
||||||
|
|
||||||
/// An Arc with mutable data protected by a blocking mutex.
|
/// An Arc with mutable data protected by a blocking mutex.
|
||||||
#[no_freeze]
|
#[no_freeze]
|
||||||
|
@ -312,7 +312,7 @@ impl PoisonOnFail {
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
struct RWArcInner<T> { priv lock: RWLock, priv failed: bool, priv data: T }
|
struct RWArcInner<T> { lock: RWLock, failed: bool, data: T }
|
||||||
/**
|
/**
|
||||||
* A dual-mode Arc protected by a reader-writer lock. The data can be accessed
|
* A dual-mode Arc protected by a reader-writer lock. The data can be accessed
|
||||||
* mutably or immutably, and immutably-accessing tasks may run concurrently.
|
* mutably or immutably, and immutably-accessing tasks may run concurrently.
|
||||||
|
|
|
@ -38,12 +38,12 @@ pub struct DList<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Link<T> = Option<~Node<T>>;
|
type Link<T> = Option<~Node<T>>;
|
||||||
struct Rawlink<T> { priv p: *mut T }
|
struct Rawlink<T> { p: *mut T }
|
||||||
|
|
||||||
struct Node<T> {
|
struct Node<T> {
|
||||||
priv next: Link<T>,
|
next: Link<T>,
|
||||||
priv prev: Rawlink<Node<T>>,
|
prev: Rawlink<Node<T>>,
|
||||||
priv value: T,
|
value: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Double-ended DList iterator
|
/// Double-ended DList iterator
|
||||||
|
|
|
@ -43,13 +43,13 @@ use std::to_bytes::Cb;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::cast;
|
use std::cast;
|
||||||
|
|
||||||
struct KeyRef<K> { priv k: *K }
|
struct KeyRef<K> { k: *K }
|
||||||
|
|
||||||
struct LruEntry<K, V> {
|
struct LruEntry<K, V> {
|
||||||
priv key: Option<K>,
|
key: Option<K>,
|
||||||
priv value: Option<V>,
|
value: Option<V>,
|
||||||
priv next: *mut LruEntry<K, V>,
|
next: *mut LruEntry<K, V>,
|
||||||
priv prev: *mut LruEntry<K, V>,
|
prev: *mut LruEntry<K, V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An LRU Cache.
|
/// An LRU Cache.
|
||||||
|
|
|
@ -709,8 +709,8 @@ pub struct Barrier {
|
||||||
|
|
||||||
// The inner state of a double barrier
|
// The inner state of a double barrier
|
||||||
struct BarrierState {
|
struct BarrierState {
|
||||||
priv count: uint,
|
count: uint,
|
||||||
priv generation_id: uint,
|
generation_id: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Barrier {
|
impl Barrier {
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
use std::hashmap::{HashSet, HashMap};
|
use std::hashmap::{HashSet, HashMap};
|
||||||
use std::util;
|
use std::util;
|
||||||
|
|
||||||
|
use metadata::csearch;
|
||||||
use middle::resolve;
|
use middle::resolve;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use middle::typeck::{method_map, method_origin, method_param};
|
use middle::typeck::{method_map, method_origin, method_param};
|
||||||
|
@ -123,22 +124,7 @@ impl Visitor<()> for ParentVisitor {
|
||||||
// While we have the id of the struct definition, go ahead and parent
|
// While we have the id of the struct definition, go ahead and parent
|
||||||
// all the fields.
|
// all the fields.
|
||||||
for field in s.fields.iter() {
|
for field in s.fields.iter() {
|
||||||
let vis = match field.node.kind {
|
self.parents.insert(field.node.id, self.curparent);
|
||||||
ast::NamedField(_, vis) => vis,
|
|
||||||
ast::UnnamedField => continue
|
|
||||||
};
|
|
||||||
|
|
||||||
// Private fields are scoped to this module, so parent them directly
|
|
||||||
// to the module instead of the struct. This is similar to the case
|
|
||||||
// of private enum variants.
|
|
||||||
if vis == ast::Private {
|
|
||||||
self.parents.insert(field.node.id, self.curparent);
|
|
||||||
|
|
||||||
// Otherwise public fields are scoped to the visibility of the
|
|
||||||
// struct itself
|
|
||||||
} else {
|
|
||||||
self.parents.insert(field.node.id, n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
visit::walk_struct_def(self, s, i, g, n, ())
|
visit::walk_struct_def(self, s, i, g, n, ())
|
||||||
}
|
}
|
||||||
|
@ -558,12 +544,48 @@ impl<'a> PrivacyVisitor<'a> {
|
||||||
|
|
||||||
// Checks that a field is in scope.
|
// Checks that a field is in scope.
|
||||||
// FIXME #6993: change type (and name) from Ident to Name
|
// FIXME #6993: change type (and name) from Ident to Name
|
||||||
fn check_field(&mut self, span: Span, id: ast::DefId, ident: ast::Ident) {
|
fn check_field(&mut self, span: Span, id: ast::DefId, ident: ast::Ident,
|
||||||
|
enum_id: Option<ast::DefId>) {
|
||||||
let fields = ty::lookup_struct_fields(self.tcx, id);
|
let fields = ty::lookup_struct_fields(self.tcx, id);
|
||||||
|
let struct_vis = if is_local(id) {
|
||||||
|
match self.tcx.items.get(id.node) {
|
||||||
|
ast_map::NodeItem(ref it, _) => it.vis,
|
||||||
|
ast_map::NodeVariant(ref v, ref it, _) => {
|
||||||
|
if v.node.vis == ast::Inherited {it.vis} else {v.node.vis}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
self.tcx.sess.span_bug(span,
|
||||||
|
format!("not an item or variant def"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let cstore = self.tcx.sess.cstore;
|
||||||
|
match enum_id {
|
||||||
|
Some(enum_id) => {
|
||||||
|
let v = csearch::get_enum_variants(self.tcx, enum_id);
|
||||||
|
match v.iter().find(|v| v.id == id) {
|
||||||
|
Some(variant) => {
|
||||||
|
if variant.vis == ast::Inherited {
|
||||||
|
csearch::get_item_visibility(cstore, enum_id)
|
||||||
|
} else {
|
||||||
|
variant.vis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.tcx.sess.span_bug(span, "no xcrate variant");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => csearch::get_item_visibility(cstore, id)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for field in fields.iter() {
|
for field in fields.iter() {
|
||||||
if field.name != ident.name { continue; }
|
if field.name != ident.name { continue; }
|
||||||
// public fields are public everywhere
|
// public structs have public fields by default, and private structs
|
||||||
if field.vis != ast::Private { break }
|
// have private fields by default.
|
||||||
|
if struct_vis == ast::Public && field.vis != ast::Private { break }
|
||||||
|
if struct_vis != ast::Public && field.vis == ast::Public { break }
|
||||||
if !is_local(field.id) ||
|
if !is_local(field.id) ||
|
||||||
!self.private_accessible(field.id.node) {
|
!self.private_accessible(field.id.node) {
|
||||||
self.tcx.sess.span_err(span, format!("field `{}` is private",
|
self.tcx.sess.span_err(span, format!("field `{}` is private",
|
||||||
|
@ -661,7 +683,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||||
let t = ty::type_autoderef(ty::expr_ty(self.tcx, base));
|
let t = ty::type_autoderef(ty::expr_ty(self.tcx, base));
|
||||||
match ty::get(t).sty {
|
match ty::get(t).sty {
|
||||||
ty::ty_struct(id, _) => {
|
ty::ty_struct(id, _) => {
|
||||||
self.check_field(expr.span, id, ident);
|
self.check_field(expr.span, id, ident, None);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -690,16 +712,18 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||||
match ty::get(ty::expr_ty(self.tcx, expr)).sty {
|
match ty::get(ty::expr_ty(self.tcx, expr)).sty {
|
||||||
ty::ty_struct(id, _) => {
|
ty::ty_struct(id, _) => {
|
||||||
for field in (*fields).iter() {
|
for field in (*fields).iter() {
|
||||||
self.check_field(expr.span, id, field.ident.node);
|
self.check_field(expr.span, id, field.ident.node,
|
||||||
|
None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ty_enum(_, _) => {
|
ty::ty_enum(_, _) => {
|
||||||
let def_map = self.tcx.def_map.borrow();
|
let def_map = self.tcx.def_map.borrow();
|
||||||
match def_map.get().get_copy(&expr.id) {
|
match def_map.get().get_copy(&expr.id) {
|
||||||
ast::DefVariant(_, variant_id, _) => {
|
ast::DefVariant(enum_id, variant_id, _) => {
|
||||||
for field in fields.iter() {
|
for field in fields.iter() {
|
||||||
self.check_field(expr.span, variant_id,
|
self.check_field(expr.span, variant_id,
|
||||||
field.ident.node);
|
field.ident.node,
|
||||||
|
Some(enum_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => self.tcx.sess.span_bug(expr.span,
|
_ => self.tcx.sess.span_bug(expr.span,
|
||||||
|
@ -763,16 +787,17 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||||
match ty::get(ty::pat_ty(self.tcx, pattern)).sty {
|
match ty::get(ty::pat_ty(self.tcx, pattern)).sty {
|
||||||
ty::ty_struct(id, _) => {
|
ty::ty_struct(id, _) => {
|
||||||
for field in fields.iter() {
|
for field in fields.iter() {
|
||||||
self.check_field(pattern.span, id, field.ident);
|
self.check_field(pattern.span, id, field.ident,
|
||||||
|
None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ty_enum(_, _) => {
|
ty::ty_enum(_, _) => {
|
||||||
let def_map = self.tcx.def_map.borrow();
|
let def_map = self.tcx.def_map.borrow();
|
||||||
match def_map.get().find(&pattern.id) {
|
match def_map.get().find(&pattern.id) {
|
||||||
Some(&ast::DefVariant(_, variant_id, _)) => {
|
Some(&ast::DefVariant(enum_id, variant_id, _)) => {
|
||||||
for field in fields.iter() {
|
for field in fields.iter() {
|
||||||
self.check_field(pattern.span, variant_id,
|
self.check_field(pattern.span, variant_id,
|
||||||
field.ident);
|
field.ident, Some(enum_id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => self.tcx.sess.span_bug(pattern.span,
|
_ => self.tcx.sess.span_bug(pattern.span,
|
||||||
|
@ -888,15 +913,22 @@ impl SanePrivacyVisitor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let check_struct = |def: &@ast::StructDef| {
|
let check_struct = |def: &@ast::StructDef,
|
||||||
|
vis: ast::Visibility,
|
||||||
|
parent_vis: Option<ast::Visibility>| {
|
||||||
|
let public_def = match vis {
|
||||||
|
ast::Public => true,
|
||||||
|
ast::Inherited | ast::Private => parent_vis == Some(ast::Public),
|
||||||
|
};
|
||||||
for f in def.fields.iter() {
|
for f in def.fields.iter() {
|
||||||
match f.node.kind {
|
match f.node.kind {
|
||||||
ast::NamedField(_, ast::Public) => {
|
ast::NamedField(_, ast::Public) if public_def => {
|
||||||
tcx.sess.span_err(f.span, "unnecessary `pub` \
|
tcx.sess.span_err(f.span, "unnecessary `pub` \
|
||||||
visibility");
|
visibility");
|
||||||
}
|
}
|
||||||
ast::NamedField(_, ast::Private) => {
|
ast::NamedField(_, ast::Private) if !public_def => {
|
||||||
// Fields should really be private by default...
|
tcx.sess.span_err(f.span, "unnecessary `priv` \
|
||||||
|
visibility");
|
||||||
}
|
}
|
||||||
ast::NamedField(..) | ast::UnnamedField => {}
|
ast::NamedField(..) | ast::UnnamedField => {}
|
||||||
}
|
}
|
||||||
|
@ -951,13 +983,15 @@ impl SanePrivacyVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
match v.node.kind {
|
match v.node.kind {
|
||||||
ast::StructVariantKind(ref s) => check_struct(s),
|
ast::StructVariantKind(ref s) => {
|
||||||
|
check_struct(s, v.node.vis, Some(item.vis));
|
||||||
|
}
|
||||||
ast::TupleVariantKind(..) => {}
|
ast::TupleVariantKind(..) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::ItemStruct(ref def, _) => check_struct(def),
|
ast::ItemStruct(ref def, _) => check_struct(def, item.vis, None),
|
||||||
|
|
||||||
ast::ItemTrait(_, _, ref methods) => {
|
ast::ItemTrait(_, _, ref methods) => {
|
||||||
for m in methods.iter() {
|
for m in methods.iter() {
|
||||||
|
|
|
@ -257,7 +257,7 @@ pub type ctxt = @ctxt_;
|
||||||
/// The data structure to keep track of all the information that typechecker
|
/// The data structure to keep track of all the information that typechecker
|
||||||
/// generates so that so that it can be reused and doesn't have to be redone
|
/// generates so that so that it can be reused and doesn't have to be redone
|
||||||
/// later on.
|
/// later on.
|
||||||
struct ctxt_ {
|
pub struct ctxt_ {
|
||||||
diag: @syntax::diagnostic::SpanHandler,
|
diag: @syntax::diagnostic::SpanHandler,
|
||||||
interner: RefCell<HashMap<intern_key, ~t_box_>>,
|
interner: RefCell<HashMap<intern_key, ~t_box_>>,
|
||||||
next_id: Cell<uint>,
|
next_id: Cell<uint>,
|
||||||
|
|
|
@ -109,8 +109,8 @@ trait FixedBuffer {
|
||||||
|
|
||||||
/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
|
/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
|
||||||
struct FixedBuffer64 {
|
struct FixedBuffer64 {
|
||||||
priv buffer: [u8, ..64],
|
buffer: [u8, ..64],
|
||||||
priv buffer_idx: uint,
|
buffer_idx: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FixedBuffer64 {
|
impl FixedBuffer64 {
|
||||||
|
|
|
@ -78,8 +78,8 @@ fn prefixes(p: &Path) -> Prefixes {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Prefixes {
|
struct Prefixes {
|
||||||
priv components: ~[~str],
|
components: ~[~str],
|
||||||
priv remaining: ~[~str]
|
remaining: ~[~str]
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator<(Path, Path)> for Prefixes {
|
impl Iterator<(Path, Path)> for Prefixes {
|
||||||
|
|
|
@ -126,7 +126,7 @@ pub trait HomingIO {
|
||||||
/// task back to its appropriate home (if applicable). The field is used to
|
/// task back to its appropriate home (if applicable). The field is used to
|
||||||
/// assert that we are where we think we are.
|
/// assert that we are where we think we are.
|
||||||
struct HomingMissile {
|
struct HomingMissile {
|
||||||
priv io_home: uint,
|
io_home: uint,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HomingMissile {
|
impl HomingMissile {
|
||||||
|
|
|
@ -95,7 +95,7 @@ pub struct Handle<'port, T> {
|
||||||
priv port: &'port mut Port<T>,
|
priv port: &'port mut Port<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Packets { priv cur: *mut Packet }
|
struct Packets { cur: *mut Packet }
|
||||||
|
|
||||||
impl Select {
|
impl Select {
|
||||||
/// Creates a new selection structure. This set is initially empty and
|
/// Creates a new selection structure. This set is initially empty and
|
||||||
|
|
|
@ -122,7 +122,7 @@ struct PathSegmentAndBoundSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A path paired with optional type bounds.
|
/// A path paired with optional type bounds.
|
||||||
struct PathAndBounds {
|
pub struct PathAndBounds {
|
||||||
path: ast::Path,
|
path: ast::Path,
|
||||||
bounds: Option<OptVec<TyParamBound>>,
|
bounds: Option<OptVec<TyParamBound>>,
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
// part of issue-6919.rs
|
// part of issue-6919.rs
|
||||||
|
|
||||||
struct C<'a> {
|
struct C<'a> {
|
||||||
k: 'a ||,
|
pub k: 'a ||,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_op() { }
|
fn no_op() { }
|
||||||
|
|
19
src/test/auxiliary/struct-field-privacy.rs
Normal file
19
src/test/auxiliary/struct-field-privacy.rs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
a: int,
|
||||||
|
pub b: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct B {
|
||||||
|
a: int,
|
||||||
|
priv b: int,
|
||||||
|
}
|
|
@ -18,8 +18,8 @@ fn iterate<'a, T>(x: T, f: 'a |&T| -> T) -> Iterate<'a, T> {
|
||||||
Iterate {f: f, next: x}
|
Iterate {f: f, next: x}
|
||||||
}
|
}
|
||||||
struct Iterate<'a, T> {
|
struct Iterate<'a, T> {
|
||||||
priv f: 'a |&T| -> T,
|
f: 'a |&T| -> T,
|
||||||
priv next: T
|
next: T
|
||||||
}
|
}
|
||||||
impl<'a, T> Iterator<T> for Iterate<'a, T> {
|
impl<'a, T> Iterator<T> for Iterate<'a, T> {
|
||||||
fn next(&mut self) -> Option<T> {
|
fn next(&mut self) -> Option<T> {
|
||||||
|
@ -35,7 +35,7 @@ enum List<'a, T> {
|
||||||
Cons(T, &'a List<'a, T>)
|
Cons(T, &'a List<'a, T>)
|
||||||
}
|
}
|
||||||
struct ListIterator<'a, T> {
|
struct ListIterator<'a, T> {
|
||||||
priv cur: &'a List<'a, T>
|
cur: &'a List<'a, T>
|
||||||
}
|
}
|
||||||
impl<'a, T> List<'a, T> {
|
impl<'a, T> List<'a, T> {
|
||||||
fn iter(&'a self) -> ListIterator<'a, T> {
|
fn iter(&'a self) -> ListIterator<'a, T> {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
struct Foo {
|
struct Foo {
|
||||||
a: int,
|
a: int,
|
||||||
priv b: int,
|
b: int,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PubFoo { //~ ERROR: missing documentation
|
pub struct PubFoo { //~ ERROR: missing documentation
|
||||||
|
@ -99,7 +99,7 @@ mod a {
|
||||||
enum Baz {
|
enum Baz {
|
||||||
BazA {
|
BazA {
|
||||||
a: int,
|
a: int,
|
||||||
priv b: int
|
b: int
|
||||||
},
|
},
|
||||||
BarB
|
BarB
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
51
src/test/compile-fail/struct-field-privacy.rs
Normal file
51
src/test/compile-fail/struct-field-privacy.rs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||||
|
// file at the top-level directory of this distribution and at
|
||||||
|
// http://rust-lang.org/COPYRIGHT.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||||
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
|
// option. This file may not be copied, modified, or distributed
|
||||||
|
// except according to those terms.
|
||||||
|
|
||||||
|
// aux-build:struct-field-privacy.rs
|
||||||
|
|
||||||
|
extern mod xc = "struct-field-privacy";
|
||||||
|
|
||||||
|
struct A {
|
||||||
|
a: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
mod inner {
|
||||||
|
struct A {
|
||||||
|
a: int,
|
||||||
|
pub b: int,
|
||||||
|
priv c: int, //~ ERROR: unnecessary `priv` visibility
|
||||||
|
}
|
||||||
|
pub struct B {
|
||||||
|
a: int,
|
||||||
|
priv b: int,
|
||||||
|
pub c: int, //~ ERROR: unnecessary `pub` visibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test(a: A, b: inner::A, c: inner::B, d: xc::A, e: xc::B) {
|
||||||
|
//~^ ERROR: type `A` is private
|
||||||
|
//~^^ ERROR: struct `A` is private
|
||||||
|
|
||||||
|
a.a;
|
||||||
|
b.a; //~ ERROR: field `a` is private
|
||||||
|
b.b;
|
||||||
|
b.c; //~ ERROR: field `c` is private
|
||||||
|
c.a;
|
||||||
|
c.b; //~ ERROR: field `b` is private
|
||||||
|
c.c;
|
||||||
|
|
||||||
|
d.a; //~ ERROR: field `a` is private
|
||||||
|
d.b;
|
||||||
|
|
||||||
|
e.a;
|
||||||
|
e.b; //~ ERROR: field `b` is private
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -8,8 +8,8 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct A { pub i: int } //~ ERROR: unnecessary `pub`
|
struct A { pub i: int }
|
||||||
struct B { priv i: int } // don't warn b/c B can still be returned
|
struct B { priv i: int } //~ ERROR: unnecessary `priv`
|
||||||
pub enum C { pub Variant } //~ ERROR: unnecessary `pub`
|
pub enum C { pub Variant } //~ ERROR: unnecessary `pub`
|
||||||
enum D { priv Variant2 } //~ ERROR: unnecessary `priv`
|
enum D { priv Variant2 } //~ ERROR: unnecessary `priv`
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ trait noisy {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dog {
|
struct dog {
|
||||||
priv barks: uint,
|
barks: uint,
|
||||||
|
|
||||||
volume: int,
|
volume: int,
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ fn dog() -> dog {
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows: uint,
|
meows: uint,
|
||||||
|
|
||||||
how_hungry: int,
|
how_hungry: int,
|
||||||
name: ~str,
|
name: ~str,
|
||||||
|
|
|
@ -15,7 +15,7 @@ trait noisy {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows: uint,
|
meows: uint,
|
||||||
how_hungry: int,
|
how_hungry: int,
|
||||||
name: ~str,
|
name: ~str,
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl cmp::Eq for cat_type {
|
||||||
// ok: T should be in scope when resolving the trait ref for map
|
// ok: T should be in scope when resolving the trait ref for map
|
||||||
struct cat<T> {
|
struct cat<T> {
|
||||||
// Yes, you can have negative meows
|
// Yes, you can have negative meows
|
||||||
priv meows : int,
|
meows : int,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
name : T,
|
name : T,
|
||||||
|
|
|
@ -14,7 +14,7 @@ extern mod cci_class_trait;
|
||||||
use cci_class_trait::animals::noisy;
|
use cci_class_trait::animals::noisy;
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows: uint,
|
meows: uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
name : ~str,
|
name : ~str,
|
||||||
|
|
|
@ -16,7 +16,7 @@ trait noisy {
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
name : ~str,
|
name : ~str,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat<U> {
|
struct cat<U> {
|
||||||
priv info : ~[U],
|
info : ~[U],
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
// xfail-fast
|
// xfail-fast
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
name : ~str,
|
name : ~str,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat<U> {
|
struct cat<U> {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
name : ~str,
|
name : ~str,
|
||||||
|
|
|
@ -47,8 +47,8 @@ struct Rect {
|
||||||
struct AsciiArt {
|
struct AsciiArt {
|
||||||
width: uint,
|
width: uint,
|
||||||
height: uint,
|
height: uint,
|
||||||
priv fill: char,
|
fill: char,
|
||||||
priv lines: ~[~[char]],
|
lines: ~[~[char]],
|
||||||
|
|
||||||
// This struct can be quite large so we'll disable copying: developers need
|
// This struct can be quite large so we'll disable copying: developers need
|
||||||
// to either pass these structs around via references or move them.
|
// to either pass these structs around via references or move them.
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
struct cat {
|
struct cat {
|
||||||
priv meows : uint,
|
meows : uint,
|
||||||
|
|
||||||
how_hungry : int,
|
how_hungry : int,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue