First stage of struct variant field visibility changes
We need a snapshot before the parser can be adjusted.
This commit is contained in:
parent
b80edf1d12
commit
00741a2c27
10 changed files with 94 additions and 69 deletions
|
@ -51,7 +51,8 @@ struct MarkSymbolVisitor<'a, 'tcx: 'a> {
|
||||||
tcx: &'a ty::ctxt<'tcx>,
|
tcx: &'a ty::ctxt<'tcx>,
|
||||||
live_symbols: Box<HashSet<ast::NodeId>>,
|
live_symbols: Box<HashSet<ast::NodeId>>,
|
||||||
struct_has_extern_repr: bool,
|
struct_has_extern_repr: bool,
|
||||||
ignore_non_const_paths: bool
|
ignore_non_const_paths: bool,
|
||||||
|
inherited_pub_visibility: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
|
@ -62,7 +63,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
live_symbols: box HashSet::new(),
|
live_symbols: box HashSet::new(),
|
||||||
struct_has_extern_repr: false,
|
struct_has_extern_repr: false,
|
||||||
ignore_non_const_paths: false
|
ignore_non_const_paths: false,
|
||||||
|
inherited_pub_visibility: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +208,8 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
fn visit_node(&mut self, node: &ast_map::Node) {
|
fn visit_node(&mut self, node: &ast_map::Node) {
|
||||||
let had_extern_repr = self.struct_has_extern_repr;
|
let had_extern_repr = self.struct_has_extern_repr;
|
||||||
self.struct_has_extern_repr = false;
|
self.struct_has_extern_repr = false;
|
||||||
|
let had_inherited_pub_visibility = self.inherited_pub_visibility;
|
||||||
|
self.inherited_pub_visibility = false;
|
||||||
match *node {
|
match *node {
|
||||||
ast_map::NodeItem(item) => {
|
ast_map::NodeItem(item) => {
|
||||||
match item.node {
|
match item.node {
|
||||||
|
@ -217,8 +221,11 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
|
|
||||||
visit::walk_item(self, &*item);
|
visit::walk_item(self, &*item);
|
||||||
}
|
}
|
||||||
|
ast::ItemEnum(..) => {
|
||||||
|
self.inherited_pub_visibility = item.vis == ast::Public;
|
||||||
|
visit::walk_item(self, &*item);
|
||||||
|
}
|
||||||
ast::ItemFn(..)
|
ast::ItemFn(..)
|
||||||
| ast::ItemEnum(..)
|
|
||||||
| ast::ItemTy(..)
|
| ast::ItemTy(..)
|
||||||
| ast::ItemStatic(..)
|
| ast::ItemStatic(..)
|
||||||
| ast::ItemConst(..) => {
|
| ast::ItemConst(..) => {
|
||||||
|
@ -244,6 +251,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
self.struct_has_extern_repr = had_extern_repr;
|
self.struct_has_extern_repr = had_extern_repr;
|
||||||
|
self.inherited_pub_visibility = had_inherited_pub_visibility;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,8 +260,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for MarkSymbolVisitor<'a, 'tcx> {
|
||||||
fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident,
|
fn visit_struct_def(&mut self, def: &ast::StructDef, _: ast::Ident,
|
||||||
_: &ast::Generics, _: ast::NodeId) {
|
_: &ast::Generics, _: ast::NodeId) {
|
||||||
let has_extern_repr = self.struct_has_extern_repr;
|
let has_extern_repr = self.struct_has_extern_repr;
|
||||||
|
let inherited_pub_visibility = self.inherited_pub_visibility;
|
||||||
let live_fields = def.fields.iter().filter(|f| {
|
let live_fields = def.fields.iter().filter(|f| {
|
||||||
has_extern_repr || match f.node.kind {
|
has_extern_repr || inherited_pub_visibility || match f.node.kind {
|
||||||
ast::NamedField(_, ast::Public) => true,
|
ast::NamedField(_, ast::Public) => true,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
|
|
|
@ -668,10 +668,8 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
|
||||||
let struct_desc = match ty::get(struct_type).sty {
|
let struct_desc = match ty::get(struct_type).sty {
|
||||||
ty::ty_struct(_, _) =>
|
ty::ty_struct(_, _) =>
|
||||||
format!("struct `{}`", ty::item_path_str(self.tcx, id)),
|
format!("struct `{}`", ty::item_path_str(self.tcx, id)),
|
||||||
ty::ty_enum(enum_id, _) =>
|
// struct variant fields have inherited visibility
|
||||||
format!("variant `{}` of enum `{}`",
|
ty::ty_enum(..) => return,
|
||||||
ty::with_path(self.tcx, id, |mut p| p.last().unwrap()),
|
|
||||||
ty::item_path_str(self.tcx, enum_id)),
|
|
||||||
_ => self.tcx.sess.span_bug(span, "can't find struct for field")
|
_ => self.tcx.sess.span_bug(span, "can't find struct for field")
|
||||||
};
|
};
|
||||||
let msg = match name {
|
let msg = match name {
|
||||||
|
@ -1214,11 +1212,6 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
|
||||||
ast::ItemEnum(ref def, _) => {
|
ast::ItemEnum(ref def, _) => {
|
||||||
for v in def.variants.iter() {
|
for v in def.variants.iter() {
|
||||||
check_inherited(tcx, v.span, v.node.vis);
|
check_inherited(tcx, v.span, v.node.vis);
|
||||||
|
|
||||||
match v.node.kind {
|
|
||||||
ast::StructVariantKind(ref s) => check_struct(&**s),
|
|
||||||
ast::TupleVariantKind(..) => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub struct BTree<V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum TreeItem<V> {
|
pub enum TreeItem<V> {
|
||||||
TreeLeaf { pub value: V },
|
TreeLeaf { value: V },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn leaf<V>(value: V) -> TreeItem<V> {
|
pub fn leaf<V>(value: V) -> TreeItem<V> {
|
||||||
|
|
|
@ -7,11 +7,9 @@
|
||||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||||
// 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.
|
||||||
|
|
||||||
#![feature(struct_variant)]
|
#![feature(struct_variant)]
|
||||||
|
|
||||||
pub enum Foo {
|
enum Bar {
|
||||||
Bar {
|
Baz { a: int }
|
||||||
baz: int
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,5 +15,5 @@
|
||||||
|
|
||||||
pub enum Enum {
|
pub enum Enum {
|
||||||
Variant(u8),
|
Variant(u8),
|
||||||
StructVariant { pub arg: u8 }
|
StructVariant { arg: u8 }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
// 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-struct-variant.rs
|
|
||||||
|
|
||||||
#![feature(struct_variant)]
|
|
||||||
|
|
||||||
extern crate "privacy-struct-variant" as other;
|
|
||||||
|
|
||||||
mod a {
|
|
||||||
pub enum Foo {
|
|
||||||
Bar {
|
|
||||||
baz: int
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test() {
|
|
||||||
let foo = Bar { baz: 42 };
|
|
||||||
|
|
||||||
let Bar { baz: _ } = foo;
|
|
||||||
match foo { Bar { baz: _ } => {} }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let foo = a::Bar { baz: 42 };
|
|
||||||
//~^ ERROR: field `baz` of variant `Bar` of enum `a::Foo` is private
|
|
||||||
|
|
||||||
let a::Bar { baz: _ } = foo;
|
|
||||||
//~^ ERROR: field `baz` of variant `Bar` of enum `a::Foo` is private
|
|
||||||
match foo { a::Bar { baz: _ } => {} }
|
|
||||||
//~^ ERROR: field `baz` of variant `Bar` of enum `a::Foo` is private
|
|
||||||
//
|
|
||||||
let foo = other::Bar { baz: 42 };
|
|
||||||
//~^ ERROR: field `baz` of variant `Bar` of enum `privacy-struct-variant::Foo` is private
|
|
||||||
|
|
||||||
let other::Bar { baz: _ } = foo;
|
|
||||||
//~^ ERROR: field `baz` of variant `Bar` of enum `privacy-struct-variant::Foo` is private
|
|
||||||
match foo { other::Bar { baz: _ } => {} }
|
|
||||||
//~^ ERROR: field `baz` of variant `Bar` of enum `privacy-struct-variant::Foo` is private
|
|
||||||
}
|
|
23
src/test/compile-fail/struct-variant-privacy-xc.rs
Normal file
23
src/test/compile-fail/struct-variant-privacy-xc.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// 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_variant_privacy.rs
|
||||||
|
#![feature(struct_variant)]
|
||||||
|
|
||||||
|
extern crate struct_variant_privacy;
|
||||||
|
|
||||||
|
fn f(b: struct_variant_privacy::Bar) { //~ ERROR enum `Bar` is private
|
||||||
|
match b {
|
||||||
|
struct_variant_privacy::Bar::Baz { a: _a } => {} //~ ERROR variant `Baz` is private
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
|
|
25
src/test/compile-fail/struct-variant-privacy.rs
Normal file
25
src/test/compile-fail/struct-variant-privacy.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// 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.
|
||||||
|
#![feature(struct_variant)]
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
enum Bar {
|
||||||
|
Baz { a: int }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f(b: foo::Bar) { //~ ERROR enum `Bar` is private
|
||||||
|
match b {
|
||||||
|
foo::Bar::Baz { a: _a } => {} //~ ERROR variant `Baz` is inaccessible
|
||||||
|
// ^~ ERROR enum `Bar` is private
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -13,7 +13,7 @@
|
||||||
#[deny(dead_code)]
|
#[deny(dead_code)]
|
||||||
pub enum Foo {
|
pub enum Foo {
|
||||||
Bar {
|
Bar {
|
||||||
pub baz: int
|
baz: int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
25
src/test/run-pass/struct-variant-field-visibility.rs
Normal file
25
src/test/run-pass/struct-variant-field-visibility.rs
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#![feature(struct_variant)]
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
pub enum Foo {
|
||||||
|
Bar { a: int }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn f(f: foo::Foo) {
|
||||||
|
match f {
|
||||||
|
foo::Foo::Bar { a: _a } => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue