Skip to content

Change struct fields to inherit privacy of the struct #11777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 26, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions doc/guide-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Reaching the end of the iterator is signalled by returning `None` instead of
# fn main() {}
/// A stream of N zeroes
struct ZeroStream {
priv remaining: uint
remaining: uint
}

impl ZeroStream {
Expand Down Expand Up @@ -305,7 +305,7 @@ The `ZeroStream` from earlier can provide an exact lower and upper bound:
# fn main() {}
/// A stream of N zeroes
struct ZeroStream {
priv remaining: uint
remaining: uint
}

impl ZeroStream {
Expand Down
4 changes: 2 additions & 2 deletions src/libextra/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ impl<T:Freeze + Send> Clone for Arc<T> {
****************************************************************************/

#[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.
#[no_freeze]
Expand Down Expand Up @@ -312,7 +312,7 @@ impl PoisonOnFail {
****************************************************************************/

#[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
* mutably or immutably, and immutably-accessing tasks may run concurrently.
Expand Down
8 changes: 4 additions & 4 deletions src/libextra/dlist.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ pub struct DList<T> {
}

type Link<T> = Option<~Node<T>>;
struct Rawlink<T> { priv p: *mut T }
struct Rawlink<T> { p: *mut T }

struct Node<T> {
priv next: Link<T>,
priv prev: Rawlink<Node<T>>,
priv value: T,
next: Link<T>,
prev: Rawlink<Node<T>>,
value: T,
}

/// Double-ended DList iterator
Expand Down
10 changes: 5 additions & 5 deletions src/libextra/lru_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ use std::to_bytes::Cb;
use std::ptr;
use std::cast;

struct KeyRef<K> { priv k: *K }
struct KeyRef<K> { k: *K }

struct LruEntry<K, V> {
priv key: Option<K>,
priv value: Option<V>,
priv next: *mut LruEntry<K, V>,
priv prev: *mut LruEntry<K, V>,
key: Option<K>,
value: Option<V>,
next: *mut LruEntry<K, V>,
prev: *mut LruEntry<K, V>,
}

/// An LRU Cache.
Expand Down
4 changes: 2 additions & 2 deletions src/libextra/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -709,8 +709,8 @@ pub struct Barrier {

// The inner state of a double barrier
struct BarrierState {
priv count: uint,
priv generation_id: uint,
count: uint,
generation_id: uint,
}

impl Barrier {
Expand Down
98 changes: 66 additions & 32 deletions src/librustc/middle/privacy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use std::hashmap::{HashSet, HashMap};
use std::util;

use metadata::csearch;
use middle::resolve;
use middle::ty;
use middle::typeck::{method_map, method_origin, method_param};
Expand Down Expand Up @@ -123,22 +124,7 @@ impl Visitor<()> for ParentVisitor {
// While we have the id of the struct definition, go ahead and parent
// all the fields.
for field in s.fields.iter() {
let vis = match field.node.kind {
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);
}
self.parents.insert(field.node.id, self.curparent);
}
visit::walk_struct_def(self, s, i, g, n, ())
}
Expand Down Expand Up @@ -558,12 +544,48 @@ impl<'a> PrivacyVisitor<'a> {

// Checks that a field is in scope.
// 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 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() {
if field.name != ident.name { continue; }
// public fields are public everywhere
if field.vis != ast::Private { break }
// public structs have public fields by default, and private structs
// 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) ||
!self.private_accessible(field.id.node) {
self.tcx.sess.span_err(span, format!("field `{}` is private",
Expand Down Expand Up @@ -661,7 +683,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
let t = ty::type_autoderef(ty::expr_ty(self.tcx, base));
match ty::get(t).sty {
ty::ty_struct(id, _) => {
self.check_field(expr.span, id, ident);
self.check_field(expr.span, id, ident, None);
}
_ => {}
}
Expand Down Expand Up @@ -690,16 +712,18 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
match ty::get(ty::expr_ty(self.tcx, expr)).sty {
ty::ty_struct(id, _) => {
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(_, _) => {
let def_map = self.tcx.def_map.borrow();
match def_map.get().get_copy(&expr.id) {
ast::DefVariant(_, variant_id, _) => {
ast::DefVariant(enum_id, variant_id, _) => {
for field in fields.iter() {
self.check_field(expr.span, variant_id,
field.ident.node);
field.ident.node,
Some(enum_id));
}
}
_ => self.tcx.sess.span_bug(expr.span,
Expand Down Expand Up @@ -763,16 +787,17 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
match ty::get(ty::pat_ty(self.tcx, pattern)).sty {
ty::ty_struct(id, _) => {
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(_, _) => {
let def_map = self.tcx.def_map.borrow();
match def_map.get().find(&pattern.id) {
Some(&ast::DefVariant(_, variant_id, _)) => {
Some(&ast::DefVariant(enum_id, variant_id, _)) => {
for field in fields.iter() {
self.check_field(pattern.span, variant_id,
field.ident);
field.ident, Some(enum_id));
}
}
_ => self.tcx.sess.span_bug(pattern.span,
Expand Down Expand Up @@ -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() {
match f.node.kind {
ast::NamedField(_, ast::Public) => {
ast::NamedField(_, ast::Public) if public_def => {
tcx.sess.span_err(f.span, "unnecessary `pub` \
visibility");
}
ast::NamedField(_, ast::Private) => {
// Fields should really be private by default...
ast::NamedField(_, ast::Private) if !public_def => {
tcx.sess.span_err(f.span, "unnecessary `priv` \
visibility");
}
ast::NamedField(..) | ast::UnnamedField => {}
}
Expand Down Expand Up @@ -951,13 +983,15 @@ impl SanePrivacyVisitor {
}

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::ItemStruct(ref def, _) => check_struct(def),
ast::ItemStruct(ref def, _) => check_struct(def, item.vis, None),

ast::ItemTrait(_, _, ref methods) => {
for m in methods.iter() {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ pub type ctxt = @ctxt_;
/// 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
/// later on.
struct ctxt_ {
pub struct ctxt_ {
diag: @syntax::diagnostic::SpanHandler,
interner: RefCell<HashMap<intern_key, ~t_box_>>,
next_id: Cell<uint>,
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/util/sha2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ trait FixedBuffer {

/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
struct FixedBuffer64 {
priv buffer: [u8, ..64],
priv buffer_idx: uint,
buffer: [u8, ..64],
buffer_idx: uint,
}

impl FixedBuffer64 {
Expand Down
4 changes: 2 additions & 2 deletions src/librustpkg/package_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ fn prefixes(p: &Path) -> Prefixes {
}

struct Prefixes {
priv components: ~[~str],
priv remaining: ~[~str]
components: ~[~str],
remaining: ~[~str]
}

impl Iterator<(Path, Path)> for Prefixes {
Expand Down
2 changes: 1 addition & 1 deletion src/librustuv/homing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ pub trait HomingIO {
/// task back to its appropriate home (if applicable). The field is used to
/// assert that we are where we think we are.
struct HomingMissile {
priv io_home: uint,
io_home: uint,
}

impl HomingMissile {
Expand Down
2 changes: 1 addition & 1 deletion src/libstd/comm/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub struct Handle<'port, T> {
priv port: &'port mut Port<T>,
}

struct Packets { priv cur: *mut Packet }
struct Packets { cur: *mut Packet }

impl Select {
/// Creates a new selection structure. This set is initially empty and
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ struct PathSegmentAndBoundSet {
}

/// A path paired with optional type bounds.
struct PathAndBounds {
pub struct PathAndBounds {
path: ast::Path,
bounds: Option<OptVec<TyParamBound>>,
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/auxiliary/iss.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
// part of issue-6919.rs

struct C<'a> {
k: 'a ||,
pub k: 'a ||,
}

fn no_op() { }
Expand Down
19 changes: 19 additions & 0 deletions src/test/auxiliary/struct-field-privacy.rs
Original file line number Diff line number Diff line change
@@ -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,
}
6 changes: 3 additions & 3 deletions src/test/bench/shootout-meteor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ fn iterate<'a, T>(x: T, f: 'a |&T| -> T) -> Iterate<'a, T> {
Iterate {f: f, next: x}
}
struct Iterate<'a, T> {
priv f: 'a |&T| -> T,
priv next: T
f: 'a |&T| -> T,
next: T
}
impl<'a, T> Iterator<T> for Iterate<'a, T> {
fn next(&mut self) -> Option<T> {
Expand All @@ -35,7 +35,7 @@ enum List<'a, T> {
Cons(T, &'a List<'a, T>)
}
struct ListIterator<'a, T> {
priv cur: &'a List<'a, T>
cur: &'a List<'a, T>
}
impl<'a, T> List<'a, T> {
fn iter(&'a self) -> ListIterator<'a, T> {
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/lint-missing-doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

struct Foo {
a: int,
priv b: int,
b: int,
}

pub struct PubFoo { //~ ERROR: missing documentation
Expand Down Expand Up @@ -99,7 +99,7 @@ mod a {
enum Baz {
BazA {
a: int,
priv b: int
b: int
},
BarB
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/mutable-class-fields-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

struct cat {
priv meows : uint,
meows : uint,

how_hungry : int,
}
Expand Down
Loading