auto merge of #13237 : alexcrichton/rust/private-tuple-structs, r=brson
This is the final commit need to implement [RFC #4](https://github.com/rust-lang/rfcs/blob/master/active/0004-private-fields.md), it makes all tuple struct fields private by default, overridable with the `pub` keyword. I'll note one divergence from the original RFC which is outlined in the first commit.
This commit is contained in:
commit
c2e457686b
@ -28,7 +28,7 @@ use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
|
||||
/// Generate Normal Random
|
||||
/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
|
||||
/// College, Oxford
|
||||
pub struct Exp1(f64);
|
||||
pub struct Exp1(pub f64);
|
||||
|
||||
// This could be done via `-rng.gen::<f64>().ln()` but that is slower.
|
||||
impl Rand for Exp1 {
|
||||
|
@ -27,7 +27,7 @@ use distributions::{ziggurat, ziggurat_tables, Sample, IndependentSample};
|
||||
/// Generate Normal Random
|
||||
/// Samples*](http://www.doornik.com/research/ziggurat.pdf). Nuffield
|
||||
/// College, Oxford
|
||||
pub struct StandardNormal(f64);
|
||||
pub struct StandardNormal(pub f64);
|
||||
|
||||
impl Rand for StandardNormal {
|
||||
fn rand<R:Rng>(rng: &mut R) -> StandardNormal {
|
||||
|
@ -666,7 +666,7 @@ pub fn random<T: Rand>() -> T {
|
||||
/// let Open01(val) = random::<Open01<f32>>();
|
||||
/// println!("f32 from (0,1): {}", val);
|
||||
/// ```
|
||||
pub struct Open01<F>(F);
|
||||
pub struct Open01<F>(pub F);
|
||||
|
||||
/// A wrapper for generating floating point numbers uniformly in the
|
||||
/// closed interval `[0,1]` (including both endpoints).
|
||||
@ -682,7 +682,7 @@ pub struct Open01<F>(F);
|
||||
/// let Closed01(val) = random::<Closed01<f32>>();
|
||||
/// println!("f32 from [0,1]: {}", val);
|
||||
/// ```
|
||||
pub struct Closed01<F>(F);
|
||||
pub struct Closed01<F>(pub F);
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
@ -290,3 +290,11 @@ pub fn get_exported_macros(cstore: &cstore::CStore,
|
||||
let cdata = cstore.get_crate_data(crate_num);
|
||||
decoder::get_exported_macros(cdata)
|
||||
}
|
||||
|
||||
pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
|
||||
def_id: ast::DefId)
|
||||
-> Option<ast::DefId>
|
||||
{
|
||||
let cdata = cstore.get_crate_data(def_id.krate);
|
||||
decoder::get_tuple_struct_definition_if_ctor(cdata, def_id.node)
|
||||
}
|
||||
|
@ -929,23 +929,26 @@ pub fn get_static_methods_if_impl(intr: Rc<IdentInterner>,
|
||||
/// If node_id is the constructor of a tuple struct, retrieve the NodeId of
|
||||
/// the actual type definition, otherwise, return None
|
||||
pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
|
||||
node_id: ast::NodeId) -> Option<ast::NodeId> {
|
||||
node_id: ast::NodeId)
|
||||
-> Option<ast::DefId>
|
||||
{
|
||||
let item = lookup_item(node_id, cdata.data());
|
||||
let mut ret = None;
|
||||
reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor, |_| {
|
||||
ret = Some(item_reqd_and_translated_parent_item(cdata.cnum, item));
|
||||
false
|
||||
});
|
||||
ret.map(|x| x.node)
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn get_item_attrs(cdata: Cmd,
|
||||
node_id: ast::NodeId,
|
||||
orig_node_id: ast::NodeId,
|
||||
f: |Vec<@ast::MetaItem> |) {
|
||||
// The attributes for a tuple struct are attached to the definition, not the ctor;
|
||||
// we assume that someone passing in a tuple struct ctor is actually wanting to
|
||||
// look at the definition
|
||||
let node_id = get_tuple_struct_definition_if_ctor(cdata, node_id).unwrap_or(node_id);
|
||||
let node_id = get_tuple_struct_definition_if_ctor(cdata, orig_node_id);
|
||||
let node_id = node_id.map(|x| x.node).unwrap_or(orig_node_id);
|
||||
let item = lookup_item(node_id, cdata.data());
|
||||
reader::tagged_docs(item, tag_attributes, |attributes| {
|
||||
reader::tagged_docs(attributes, tag_attribute, |attribute| {
|
||||
|
@ -56,11 +56,11 @@ pub struct Edge<E> {
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub struct NodeIndex(uint);
|
||||
pub struct NodeIndex(pub uint);
|
||||
pub static InvalidNodeIndex: NodeIndex = NodeIndex(uint::MAX);
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub struct EdgeIndex(uint);
|
||||
pub struct EdgeIndex(pub uint);
|
||||
pub static InvalidEdgeIndex: EdgeIndex = EdgeIndex(uint::MAX);
|
||||
|
||||
// Use a private field here to guarantee no more instances are created:
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
use std::mem::replace;
|
||||
|
||||
use metadata::csearch;
|
||||
use middle::lint;
|
||||
use middle::resolve;
|
||||
use middle::ty;
|
||||
@ -358,6 +359,12 @@ enum PrivacyResult {
|
||||
DisallowedBy(ast::NodeId),
|
||||
}
|
||||
|
||||
enum FieldName {
|
||||
UnnamedField(uint), // index
|
||||
// FIXME #6993: change type (and name) from Ident to Name
|
||||
NamedField(ast::Ident),
|
||||
}
|
||||
|
||||
impl<'a> PrivacyVisitor<'a> {
|
||||
// used when debugging
|
||||
fn nodestr(&self, id: ast::NodeId) -> ~str {
|
||||
@ -560,18 +567,23 @@ 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) {
|
||||
for field in ty::lookup_struct_fields(self.tcx, id).iter() {
|
||||
if field.name != ident.name { continue; }
|
||||
if 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",
|
||||
token::get_ident(ident)))
|
||||
fn check_field(&mut self, span: Span, id: ast::DefId,
|
||||
name: FieldName) {
|
||||
let fields = ty::lookup_struct_fields(self.tcx, id);
|
||||
let field = match name {
|
||||
NamedField(ident) => {
|
||||
fields.iter().find(|f| f.name == ident.name).unwrap()
|
||||
}
|
||||
break;
|
||||
UnnamedField(idx) => fields.get(idx)
|
||||
};
|
||||
if field.vis == ast::Public { return }
|
||||
if !is_local(field.id) || !self.private_accessible(field.id.node) {
|
||||
let msg = match name {
|
||||
NamedField(name) => format!("field `{}` is private",
|
||||
token::get_ident(name)),
|
||||
UnnamedField(idx) => format!("field \\#{} is private", idx + 1),
|
||||
};
|
||||
self.tcx.sess.span_err(span, msg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -634,10 +646,11 @@ impl<'a> PrivacyVisitor<'a> {
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
// If an import is not used in either namespace, we still want to check
|
||||
// that it could be legal. Therefore we check in both namespaces and only
|
||||
// report an error if both would be illegal. We only report one error,
|
||||
// even if it is illegal to import from both namespaces.
|
||||
// If an import is not used in either namespace, we still
|
||||
// want to check that it could be legal. Therefore we check
|
||||
// in both namespaces and only report an error if both would
|
||||
// be illegal. We only report one error, even if it is
|
||||
// illegal to import from both namespaces.
|
||||
match (value_priv, check_value, type_priv, check_type) {
|
||||
(Some(p), resolve::Unused, None, _) |
|
||||
(None, _, Some(p), resolve::Unused) => {
|
||||
@ -701,7 +714,8 @@ impl<'a> PrivacyVisitor<'a> {
|
||||
// is whether the trait itself is accessible or not.
|
||||
MethodParam(MethodParam { trait_id: trait_id, .. }) |
|
||||
MethodObject(MethodObject { trait_id: trait_id, .. }) => {
|
||||
self.report_error(self.ensure_public(span, trait_id, None, "source trait"));
|
||||
self.report_error(self.ensure_public(span, trait_id, None,
|
||||
"source trait"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -726,7 +740,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||
match ty::get(ty::expr_ty_adjusted(self.tcx, base,
|
||||
&*self.method_map.borrow())).sty {
|
||||
ty::ty_struct(id, _) => {
|
||||
self.check_field(expr.span, id, ident);
|
||||
self.check_field(expr.span, id, NamedField(ident));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -749,7 +763,8 @@ 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,
|
||||
NamedField(field.ident.node));
|
||||
}
|
||||
}
|
||||
ty::ty_enum(_, _) => {
|
||||
@ -757,7 +772,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||
ast::DefVariant(_, variant_id, _) => {
|
||||
for field in fields.iter() {
|
||||
self.check_field(expr.span, variant_id,
|
||||
field.ident.node);
|
||||
NamedField(field.ident.node));
|
||||
}
|
||||
}
|
||||
_ => self.tcx.sess.span_bug(expr.span,
|
||||
@ -772,6 +787,46 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||
struct type?!"),
|
||||
}
|
||||
}
|
||||
ast::ExprPath(..) => {
|
||||
let guard = |did: ast::DefId| {
|
||||
let fields = ty::lookup_struct_fields(self.tcx, did);
|
||||
let any_priv = fields.iter().any(|f| {
|
||||
f.vis != ast::Public && (
|
||||
!is_local(f.id) ||
|
||||
!self.private_accessible(f.id.node))
|
||||
});
|
||||
if any_priv {
|
||||
self.tcx.sess.span_err(expr.span,
|
||||
"cannot invoke tuple struct constructor \
|
||||
with private fields");
|
||||
}
|
||||
};
|
||||
match self.tcx.def_map.borrow().find(&expr.id) {
|
||||
Some(&ast::DefStruct(did)) => {
|
||||
guard(if is_local(did) {
|
||||
local_def(self.tcx.map.get_parent(did.node))
|
||||
} else {
|
||||
// "tuple structs" with zero fields (such as
|
||||
// `pub struct Foo;`) don't have a ctor_id, hence
|
||||
// the unwrap_or to the same struct id.
|
||||
let maybe_did =
|
||||
csearch::get_tuple_struct_definition_if_ctor(
|
||||
&self.tcx.sess.cstore, did);
|
||||
maybe_did.unwrap_or(did)
|
||||
})
|
||||
}
|
||||
// Tuple struct constructors across crates are identified as
|
||||
// DefFn types, so we explicitly handle that case here.
|
||||
Some(&ast::DefFn(did, _)) if !is_local(did) => {
|
||||
match csearch::get_tuple_struct_definition_if_ctor(
|
||||
&self.tcx.sess.cstore, did) {
|
||||
Some(did) => guard(did),
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@ -821,7 +876,8 @@ 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,
|
||||
NamedField(field.ident));
|
||||
}
|
||||
}
|
||||
ty::ty_enum(_, _) => {
|
||||
@ -829,7 +885,7 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||
Some(&ast::DefVariant(_, variant_id, _)) => {
|
||||
for field in fields.iter() {
|
||||
self.check_field(pattern.span, variant_id,
|
||||
field.ident);
|
||||
NamedField(field.ident));
|
||||
}
|
||||
}
|
||||
_ => self.tcx.sess.span_bug(pattern.span,
|
||||
@ -844,6 +900,27 @@ impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
||||
struct type?!"),
|
||||
}
|
||||
}
|
||||
|
||||
// Patterns which bind no fields are allowable (the path is check
|
||||
// elsewhere).
|
||||
ast::PatEnum(_, Some(ref fields)) => {
|
||||
match ty::get(ty::pat_ty(self.tcx, pattern)).sty {
|
||||
ty::ty_struct(id, _) => {
|
||||
for (i, field) in fields.iter().enumerate() {
|
||||
match field.node {
|
||||
ast::PatWild(..) => continue,
|
||||
_ => {}
|
||||
}
|
||||
self.check_field(field.span, id, UnnamedField(i));
|
||||
}
|
||||
}
|
||||
ty::ty_enum(..) => {
|
||||
// enum fields have no privacy at this time
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@ use lib::llvm::{llvm, BasicBlockRef};
|
||||
use middle::trans::value::{Users, Value};
|
||||
use std::iter::{Filter, Map};
|
||||
|
||||
pub struct BasicBlock(BasicBlockRef);
|
||||
pub struct BasicBlock(pub BasicBlockRef);
|
||||
|
||||
pub type Preds<'a> = Map<'a, Value, BasicBlock, Filter<'a, Value, Users>>;
|
||||
|
||||
|
@ -13,7 +13,7 @@ use middle::trans::basic_block::BasicBlock;
|
||||
use middle::trans::common::Block;
|
||||
use std::libc::c_uint;
|
||||
|
||||
pub struct Value(ValueRef);
|
||||
pub struct Value(pub ValueRef);
|
||||
|
||||
macro_rules! opt_val ( ($e:expr) => (
|
||||
unsafe {
|
||||
|
@ -866,13 +866,13 @@ impl CLike for BuiltinBound {
|
||||
}
|
||||
|
||||
#[deriving(Clone, Eq, TotalEq, Hash)]
|
||||
pub struct TyVid(uint);
|
||||
pub struct TyVid(pub uint);
|
||||
|
||||
#[deriving(Clone, Eq, TotalEq, Hash)]
|
||||
pub struct IntVid(uint);
|
||||
pub struct IntVid(pub uint);
|
||||
|
||||
#[deriving(Clone, Eq, TotalEq, Hash)]
|
||||
pub struct FloatVid(uint);
|
||||
pub struct FloatVid(pub uint);
|
||||
|
||||
#[deriving(Clone, Eq, TotalEq, Encodable, Decodable, Hash)]
|
||||
pub struct RegionVid {
|
||||
|
@ -84,7 +84,7 @@ use syntax::ast;
|
||||
// Note: Coerce is not actually a combiner, in that it does not
|
||||
// conform to the same interface, though it performs a similar
|
||||
// function.
|
||||
pub struct Coerce<'f>(CombineFields<'f>);
|
||||
pub struct Coerce<'f>(pub CombineFields<'f>);
|
||||
|
||||
impl<'f> Coerce<'f> {
|
||||
pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f> {
|
||||
|
@ -28,7 +28,7 @@ use collections::HashMap;
|
||||
use util::common::{indenter};
|
||||
use util::ppaux::mt_to_str;
|
||||
|
||||
pub struct Glb<'f>(CombineFields<'f>); // "greatest lower bound" (common subtype)
|
||||
pub struct Glb<'f>(pub CombineFields<'f>); // "greatest lower bound" (common subtype)
|
||||
|
||||
impl<'f> Glb<'f> {
|
||||
pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f> { let Glb(ref v) = *self; v }
|
||||
|
@ -27,7 +27,7 @@ use syntax::ast::{ExternFn, ImpureFn, UnsafeFn};
|
||||
use syntax::ast::{Onceness, Purity};
|
||||
use util::ppaux::mt_to_str;
|
||||
|
||||
pub struct Lub<'f>(CombineFields<'f>); // least-upper-bound: common supertype
|
||||
pub struct Lub<'f>(pub CombineFields<'f>); // least-upper-bound: common supertype
|
||||
|
||||
impl<'f> Lub<'f> {
|
||||
pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f> { let Lub(ref v) = *self; v }
|
||||
|
@ -27,7 +27,7 @@ use util::ppaux::bound_region_to_str;
|
||||
|
||||
use syntax::ast::{Onceness, Purity};
|
||||
|
||||
pub struct Sub<'f>(CombineFields<'f>); // "subtype", "subregion" etc
|
||||
pub struct Sub<'f>(pub CombineFields<'f>); // "subtype", "subregion" etc
|
||||
|
||||
impl<'f> Sub<'f> {
|
||||
pub fn get_ref<'a>(&'a self) -> &'a CombineFields<'f> { let Sub(ref v) = *self; v }
|
||||
|
@ -17,7 +17,7 @@ use std::fmt;
|
||||
|
||||
/// Wrapper struct which will emit the HTML-escaped version of the contained
|
||||
/// string when passed to a format string.
|
||||
pub struct Escape<'a>(&'a str);
|
||||
pub struct Escape<'a>(pub &'a str);
|
||||
|
||||
impl<'a> fmt::Show for Escape<'a> {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
|
@ -28,12 +28,12 @@ use html::render::{cache_key, current_location_key};
|
||||
|
||||
/// Helper to render an optional visibility with a space after it (if the
|
||||
/// visibility is preset)
|
||||
pub struct VisSpace(Option<ast::Visibility>);
|
||||
pub struct VisSpace(pub Option<ast::Visibility>);
|
||||
/// Similarly to VisSpace, this structure is used to render a purity with a
|
||||
/// space after it.
|
||||
pub struct PuritySpace(ast::Purity);
|
||||
pub struct PuritySpace(pub ast::Purity);
|
||||
/// Wrapper struct for properly emitting a method declaration.
|
||||
pub struct Method<'a>(&'a clean::SelfTy, &'a clean::FnDecl);
|
||||
pub struct Method<'a>(pub &'a clean::SelfTy, pub &'a clean::FnDecl);
|
||||
|
||||
impl VisSpace {
|
||||
pub fn get(&self) -> Option<ast::Visibility> {
|
||||
|
@ -42,10 +42,10 @@ use html::highlight;
|
||||
/// A unit struct which has the `fmt::Show` trait implemented. When
|
||||
/// formatted, this struct will emit the HTML corresponding to the rendered
|
||||
/// version of the contained markdown string.
|
||||
pub struct Markdown<'a>(&'a str);
|
||||
pub struct Markdown<'a>(pub &'a str);
|
||||
/// A unit struct like `Markdown`, that renders the markdown with a
|
||||
/// table of contents.
|
||||
pub struct MarkdownWithToc<'a>(&'a str);
|
||||
pub struct MarkdownWithToc<'a>(pub &'a str);
|
||||
|
||||
static OUTPUT_UNIT: libc::size_t = 64;
|
||||
static MKDEXT_NO_INTRA_EMPHASIS: libc::c_uint = 1 << 0;
|
||||
|
@ -58,7 +58,7 @@ pub struct Task {
|
||||
}
|
||||
|
||||
pub struct GarbageCollector;
|
||||
pub struct LocalStorage(Option<local_data::Map>);
|
||||
pub struct LocalStorage(pub Option<local_data::Map>);
|
||||
|
||||
/// A handle to a blocked task. Usually this means having the ~Task pointer by
|
||||
/// ownership, but if the task is killable, a killer can steal it at any time.
|
||||
|
@ -14,40 +14,48 @@
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
|
||||
pub struct i8x16(pub i8, pub i8, pub i8, pub i8,
|
||||
pub i8, pub i8, pub i8, pub i8,
|
||||
pub i8, pub i8, pub i8, pub i8,
|
||||
pub i8, pub i8, pub i8, pub i8);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
|
||||
pub struct i16x8(pub i16, pub i16, pub i16, pub i16,
|
||||
pub i16, pub i16, pub i16, pub i16);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct i32x4(i32, i32, i32, i32);
|
||||
pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct i64x2(i64, i64);
|
||||
pub struct i64x2(pub i64, pub i64);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
|
||||
pub struct u8x16(pub u8, pub u8, pub u8, pub u8,
|
||||
pub u8, pub u8, pub u8, pub u8,
|
||||
pub u8, pub u8, pub u8, pub u8,
|
||||
pub u8, pub u8, pub u8, pub u8);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct u16x8(u16, u16, u16, u16, u16, u16, u16, u16);
|
||||
pub struct u16x8(pub u16, pub u16, pub u16, pub u16,
|
||||
pub u16, pub u16, pub u16, pub u16);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct u32x4(u32, u32, u32, u32);
|
||||
pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct u64x2(u64, u64);
|
||||
pub struct u64x2(pub u64, pub u64);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct f32x4(f32, f32, f32, f32);
|
||||
pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
|
||||
|
||||
#[experimental]
|
||||
#[simd]
|
||||
pub struct f64x2(f64, f64);
|
||||
pub struct f64x2(pub f64, pub f64);
|
||||
|
@ -493,10 +493,10 @@ pub enum Expr_ {
|
||||
ExprVstore(@Expr, ExprVstore),
|
||||
// First expr is the place; second expr is the value.
|
||||
ExprBox(@Expr, @Expr),
|
||||
ExprVec(Vec<@Expr> , Mutability),
|
||||
ExprCall(@Expr, Vec<@Expr> ),
|
||||
ExprMethodCall(Ident, Vec<P<Ty>> , Vec<@Expr> ),
|
||||
ExprTup(Vec<@Expr> ),
|
||||
ExprVec(Vec<@Expr>, Mutability),
|
||||
ExprCall(@Expr, Vec<@Expr>),
|
||||
ExprMethodCall(Ident, Vec<P<Ty>>, Vec<@Expr>),
|
||||
ExprTup(Vec<@Expr>),
|
||||
ExprBinary(BinOp, @Expr, @Expr),
|
||||
ExprUnary(UnOp, @Expr),
|
||||
ExprLit(@Lit),
|
||||
@ -508,14 +508,14 @@ pub enum Expr_ {
|
||||
// Conditionless loop (can be exited with break, cont, or ret)
|
||||
// FIXME #6993: change to Option<Name>
|
||||
ExprLoop(P<Block>, Option<Ident>),
|
||||
ExprMatch(@Expr, Vec<Arm> ),
|
||||
ExprMatch(@Expr, Vec<Arm>),
|
||||
ExprFnBlock(P<FnDecl>, P<Block>),
|
||||
ExprProc(P<FnDecl>, P<Block>),
|
||||
ExprBlock(P<Block>),
|
||||
|
||||
ExprAssign(@Expr, @Expr),
|
||||
ExprAssignOp(BinOp, @Expr, @Expr),
|
||||
ExprField(@Expr, Ident, Vec<P<Ty>> ),
|
||||
ExprField(@Expr, Ident, Vec<P<Ty>>),
|
||||
ExprIndex(@Expr, @Expr),
|
||||
|
||||
/// Expression that looks like a "name". For example,
|
||||
|
@ -66,7 +66,7 @@ impl<'a> Iterator<PathElem> for LinkedPath<'a> {
|
||||
|
||||
// HACK(eddyb) move this into libstd (value wrapper for slice::Items).
|
||||
#[deriving(Clone)]
|
||||
pub struct Values<'a, T>(slice::Items<'a, T>);
|
||||
pub struct Values<'a, T>(pub slice::Items<'a, T>);
|
||||
|
||||
impl<'a, T: Copy> Iterator<T> for Values<'a, T> {
|
||||
fn next(&mut self) -> Option<T> {
|
||||
|
@ -33,13 +33,13 @@ pub trait Pos {
|
||||
/// A byte offset. Keep this small (currently 32-bits), as AST contains
|
||||
/// a lot of them.
|
||||
#[deriving(Clone, Eq, TotalEq, Hash, Ord, Show)]
|
||||
pub struct BytePos(u32);
|
||||
pub struct BytePos(pub u32);
|
||||
|
||||
/// A character offset. Because of multibyte utf8 characters, a byte offset
|
||||
/// is not equivalent to a character offset. The CodeMap will convert BytePos
|
||||
/// values to CharPos values as necessary.
|
||||
#[deriving(Eq, Hash, Ord, Show)]
|
||||
pub struct CharPos(uint);
|
||||
pub struct CharPos(pub uint);
|
||||
|
||||
// FIXME: Lots of boilerplate in these impls, but so far my attempts to fix
|
||||
// have been unsuccessful
|
||||
|
@ -8,7 +8,7 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub struct Closed01<F>(F);
|
||||
pub struct Closed01<F>(pub F);
|
||||
|
||||
pub trait Bar { fn new() -> Self; }
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub struct A<'a>(&'a int);
|
||||
pub struct A<'a>(pub &'a int);
|
||||
|
@ -8,4 +8,4 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub struct V2<T>(T, T);
|
||||
pub struct V2<T>(pub T, pub T);
|
||||
|
@ -8,4 +8,4 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub struct Wrap<A>(A);
|
||||
pub struct Wrap<A>(pub A);
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
|
||||
pub struct S(());
|
||||
pub struct S(pub ());
|
||||
|
||||
impl S {
|
||||
pub fn foo(&self) { }
|
||||
|
@ -161,15 +161,15 @@ pub enum Enum {
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub struct DeprecatedTupleStruct(int);
|
||||
pub struct DeprecatedTupleStruct(pub int);
|
||||
#[experimental]
|
||||
pub struct ExperimentalTupleStruct(int);
|
||||
pub struct ExperimentalTupleStruct(pub int);
|
||||
#[unstable]
|
||||
pub struct UnstableTupleStruct(int);
|
||||
pub struct UnmarkedTupleStruct(int);
|
||||
pub struct UnstableTupleStruct(pub int);
|
||||
pub struct UnmarkedTupleStruct(pub int);
|
||||
#[stable]
|
||||
pub struct StableTupleStruct(int);
|
||||
pub struct StableTupleStruct(pub int);
|
||||
#[frozen]
|
||||
pub struct FrozenTupleStruct(int);
|
||||
pub struct FrozenTupleStruct(pub int);
|
||||
#[locked]
|
||||
pub struct LockedTupleStruct(int);
|
||||
pub struct LockedTupleStruct(pub int);
|
||||
|
@ -10,4 +10,4 @@
|
||||
|
||||
#[crate_type="lib"];
|
||||
|
||||
pub struct Au(int);
|
||||
pub struct Au(pub int);
|
||||
|
14
src/test/auxiliary/privacy-tuple-struct.rs
Normal file
14
src/test/auxiliary/privacy-tuple-struct.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// 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.
|
||||
|
||||
pub struct A(());
|
||||
pub struct B(int);
|
||||
pub struct C(pub int, int);
|
||||
pub struct D(pub int);
|
137
src/test/compile-fail/privacy5.rs
Normal file
137
src/test/compile-fail/privacy5.rs
Normal file
@ -0,0 +1,137 @@
|
||||
// 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:privacy-tuple-struct.rs
|
||||
// ignore-fast
|
||||
|
||||
extern crate other = "privacy-tuple-struct";
|
||||
|
||||
mod a {
|
||||
pub struct A(());
|
||||
pub struct B(int);
|
||||
pub struct C(pub int, int);
|
||||
pub struct D(pub int);
|
||||
|
||||
fn test() {
|
||||
let a = A(());
|
||||
let b = B(2);
|
||||
let c = C(2, 3);
|
||||
let d = D(4);
|
||||
|
||||
let A(()) = a;
|
||||
let A(_) = a;
|
||||
match a { A(()) => {} }
|
||||
match a { A(_) => {} }
|
||||
|
||||
let B(_) = b;
|
||||
let B(_b) = b;
|
||||
match b { B(_) => {} }
|
||||
match b { B(_b) => {} }
|
||||
match b { B(1) => {} B(_) => {} }
|
||||
|
||||
let C(_, _) = c;
|
||||
let C(_a, _) = c;
|
||||
let C(_, _b) = c;
|
||||
let C(_a, _b) = c;
|
||||
match c { C(_, _) => {} }
|
||||
match c { C(_a, _) => {} }
|
||||
match c { C(_, _b) => {} }
|
||||
match c { C(_a, _b) => {} }
|
||||
|
||||
let D(_) = d;
|
||||
let D(_d) = d;
|
||||
match d { D(_) => {} }
|
||||
match d { D(_d) => {} }
|
||||
match d { D(1) => {} D(_) => {} }
|
||||
|
||||
let a2 = A;
|
||||
let b2 = B;
|
||||
let c2 = C;
|
||||
let d2 = D;
|
||||
}
|
||||
}
|
||||
|
||||
fn this_crate() {
|
||||
let a = a::A(()); //~ ERROR: cannot invoke tuple struct constructor
|
||||
let b = a::B(2); //~ ERROR: cannot invoke tuple struct constructor
|
||||
let c = a::C(2, 3); //~ ERROR: cannot invoke tuple struct constructor
|
||||
let d = a::D(4);
|
||||
|
||||
let a::A(()) = a; //~ ERROR: field #1 is private
|
||||
let a::A(_) = a;
|
||||
match a { a::A(()) => {} } //~ ERROR: field #1 is private
|
||||
match a { a::A(_) => {} }
|
||||
|
||||
let a::B(_) = b;
|
||||
let a::B(_b) = b; //~ ERROR: field #1 is private
|
||||
match b { a::B(_) => {} }
|
||||
match b { a::B(_b) => {} } //~ ERROR: field #1 is private
|
||||
match b { a::B(1) => {} a::B(_) => {} } //~ ERROR: field #1 is private
|
||||
|
||||
let a::C(_, _) = c;
|
||||
let a::C(_a, _) = c;
|
||||
let a::C(_, _b) = c; //~ ERROR: field #2 is private
|
||||
let a::C(_a, _b) = c; //~ ERROR: field #2 is private
|
||||
match c { a::C(_, _) => {} }
|
||||
match c { a::C(_a, _) => {} }
|
||||
match c { a::C(_, _b) => {} } //~ ERROR: field #2 is private
|
||||
match c { a::C(_a, _b) => {} } //~ ERROR: field #2 is private
|
||||
|
||||
let a::D(_) = d;
|
||||
let a::D(_d) = d;
|
||||
match d { a::D(_) => {} }
|
||||
match d { a::D(_d) => {} }
|
||||
match d { a::D(1) => {} a::D(_) => {} }
|
||||
|
||||
let a2 = a::A; //~ ERROR: cannot invoke tuple struct constructor
|
||||
let b2 = a::B; //~ ERROR: cannot invoke tuple struct constructor
|
||||
let c2 = a::C; //~ ERROR: cannot invoke tuple struct constructor
|
||||
let d2 = a::D;
|
||||
}
|
||||
|
||||
fn xcrate() {
|
||||
let a = other::A(()); //~ ERROR: cannot invoke tuple struct constructor
|
||||
let b = other::B(2); //~ ERROR: cannot invoke tuple struct constructor
|
||||
let c = other::C(2, 3); //~ ERROR: cannot invoke tuple struct constructor
|
||||
let d = other::D(4);
|
||||
|
||||
let other::A(()) = a; //~ ERROR: field #1 is private
|
||||
let other::A(_) = a;
|
||||
match a { other::A(()) => {} } //~ ERROR: field #1 is private
|
||||
match a { other::A(_) => {} }
|
||||
|
||||
let other::B(_) = b;
|
||||
let other::B(_b) = b; //~ ERROR: field #1 is private
|
||||
match b { other::B(_) => {} }
|
||||
match b { other::B(_b) => {} } //~ ERROR: field #1 is private
|
||||
match b { other::B(1) => {} other::B(_) => {} } //~ ERROR: field #1 is private
|
||||
|
||||
let other::C(_, _) = c;
|
||||
let other::C(_a, _) = c;
|
||||
let other::C(_, _b) = c; //~ ERROR: field #2 is private
|
||||
let other::C(_a, _b) = c; //~ ERROR: field #2 is private
|
||||
match c { other::C(_, _) => {} }
|
||||
match c { other::C(_a, _) => {} }
|
||||
match c { other::C(_, _b) => {} } //~ ERROR: field #2 is private
|
||||
match c { other::C(_a, _b) => {} } //~ ERROR: field #2 is private
|
||||
|
||||
let other::D(_) = d;
|
||||
let other::D(_d) = d;
|
||||
match d { other::D(_) => {} }
|
||||
match d { other::D(_d) => {} }
|
||||
match d { other::D(1) => {} other::D(_) => {} }
|
||||
|
||||
let a2 = other::A; //~ ERROR: cannot invoke tuple struct constructor
|
||||
let b2 = other::B; //~ ERROR: cannot invoke tuple struct constructor
|
||||
let c2 = other::C; //~ ERROR: cannot invoke tuple struct constructor
|
||||
let d2 = other::D;
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user