mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Correctly encode item visibility in metadata
This fixes private statics and functions from being usable cross-crates, along with some bad privacy error messages. This is a reopening of #8365 with all the privacy checks in privacy.rs instead of resolve.rs (where they should be anyway). These maps of exported items will hopefully get used for generating documentation by rustdoc Closes #8592
This commit is contained in:
parent
7535479633
commit
10a583ce1a
@ -162,7 +162,7 @@ struct MutexArcInner<T> { priv lock: Mutex, priv failed: bool, priv 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]
|
||||||
struct MutexArc<T> { priv x: UnsafeArc<MutexArcInner<T>> }
|
pub struct MutexArc<T> { priv x: UnsafeArc<MutexArcInner<T>> }
|
||||||
|
|
||||||
|
|
||||||
impl<T:Send> Clone for MutexArc<T> {
|
impl<T:Send> Clone for MutexArc<T> {
|
||||||
@ -343,7 +343,7 @@ struct RWArcInner<T> { priv lock: RWLock, priv failed: bool, priv data: T }
|
|||||||
* Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested.
|
* Unlike mutex_arcs, rw_arcs are safe, because they cannot be nested.
|
||||||
*/
|
*/
|
||||||
#[no_freeze]
|
#[no_freeze]
|
||||||
struct RWArc<T> {
|
pub struct RWArc<T> {
|
||||||
priv x: UnsafeArc<RWArcInner<T>>,
|
priv x: UnsafeArc<RWArcInner<T>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ impl WorkMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Database {
|
pub struct Database {
|
||||||
db_filename: Path,
|
db_filename: Path,
|
||||||
db_cache: TreeMap<~str, ~str>,
|
db_cache: TreeMap<~str, ~str>,
|
||||||
db_dirty: bool
|
db_dirty: bool
|
||||||
@ -207,7 +207,7 @@ impl Drop for Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Logger {
|
pub struct Logger {
|
||||||
// FIXME #4432: Fill in
|
// FIXME #4432: Fill in
|
||||||
a: ()
|
a: ()
|
||||||
}
|
}
|
||||||
@ -223,10 +223,10 @@ impl Logger {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type FreshnessMap = TreeMap<~str,extern fn(&str,&str)->bool>;
|
pub type FreshnessMap = TreeMap<~str,extern fn(&str,&str)->bool>;
|
||||||
|
|
||||||
#[deriving(Clone)]
|
#[deriving(Clone)]
|
||||||
struct Context {
|
pub struct Context {
|
||||||
db: RWArc<Database>,
|
db: RWArc<Database>,
|
||||||
logger: RWArc<Logger>,
|
logger: RWArc<Logger>,
|
||||||
cfg: Arc<json::Object>,
|
cfg: Arc<json::Object>,
|
||||||
@ -239,13 +239,13 @@ struct Context {
|
|||||||
freshness: Arc<FreshnessMap>
|
freshness: Arc<FreshnessMap>
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Prep<'self> {
|
pub struct Prep<'self> {
|
||||||
ctxt: &'self Context,
|
ctxt: &'self Context,
|
||||||
fn_name: &'self str,
|
fn_name: &'self str,
|
||||||
declared_inputs: WorkMap,
|
declared_inputs: WorkMap,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Exec {
|
pub struct Exec {
|
||||||
discovered_inputs: WorkMap,
|
discovered_inputs: WorkMap,
|
||||||
discovered_outputs: WorkMap
|
discovered_outputs: WorkMap
|
||||||
}
|
}
|
||||||
|
@ -197,6 +197,7 @@ pub fn phase_2_configure_and_expand(sess: Session,
|
|||||||
|
|
||||||
pub struct CrateAnalysis {
|
pub struct CrateAnalysis {
|
||||||
exp_map2: middle::resolve::ExportMap2,
|
exp_map2: middle::resolve::ExportMap2,
|
||||||
|
exported_items: @middle::privacy::ExportedItems,
|
||||||
ty_cx: ty::ctxt,
|
ty_cx: ty::ctxt,
|
||||||
maps: astencode::Maps,
|
maps: astencode::Maps,
|
||||||
reachable: @mut HashSet<ast::NodeId>
|
reachable: @mut HashSet<ast::NodeId>
|
||||||
@ -258,8 +259,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
|||||||
middle::check_const::check_crate(sess, crate, ast_map, def_map,
|
middle::check_const::check_crate(sess, crate, ast_map, def_map,
|
||||||
method_map, ty_cx));
|
method_map, ty_cx));
|
||||||
|
|
||||||
time(time_passes, ~"privacy checking", ||
|
let exported_items =
|
||||||
middle::privacy::check_crate(ty_cx, &method_map, crate));
|
time(time_passes, ~"privacy checking", ||
|
||||||
|
middle::privacy::check_crate(ty_cx, &method_map, &exp_map2, crate));
|
||||||
|
|
||||||
time(time_passes, ~"effect checking", ||
|
time(time_passes, ~"effect checking", ||
|
||||||
middle::effect::check_crate(ty_cx, method_map, crate));
|
middle::effect::check_crate(ty_cx, method_map, crate));
|
||||||
@ -301,6 +303,7 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
|||||||
|
|
||||||
CrateAnalysis {
|
CrateAnalysis {
|
||||||
exp_map2: exp_map2,
|
exp_map2: exp_map2,
|
||||||
|
exported_items: @exported_items,
|
||||||
ty_cx: ty_cx,
|
ty_cx: ty_cx,
|
||||||
maps: astencode::Maps {
|
maps: astencode::Maps {
|
||||||
root_map: root_map,
|
root_map: root_map,
|
||||||
|
@ -27,7 +27,8 @@ use syntax::diagnostic::expect;
|
|||||||
pub struct StaticMethodInfo {
|
pub struct StaticMethodInfo {
|
||||||
ident: ast::Ident,
|
ident: ast::Ident,
|
||||||
def_id: ast::DefId,
|
def_id: ast::DefId,
|
||||||
purity: ast::purity
|
purity: ast::purity,
|
||||||
|
vis: ast::visibility,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_symbol(cstore: @mut cstore::CStore, def: ast::DefId) -> ~str {
|
pub fn get_symbol(cstore: @mut cstore::CStore, def: ast::DefId) -> ~str {
|
||||||
@ -52,7 +53,8 @@ pub fn each_lang_item(cstore: @mut cstore::CStore,
|
|||||||
/// Iterates over each child of the given item.
|
/// Iterates over each child of the given item.
|
||||||
pub fn each_child_of_item(cstore: @mut cstore::CStore,
|
pub fn each_child_of_item(cstore: @mut cstore::CStore,
|
||||||
def_id: ast::DefId,
|
def_id: ast::DefId,
|
||||||
callback: &fn(decoder::DefLike, ast::Ident)) {
|
callback: &fn(decoder::DefLike, ast::Ident,
|
||||||
|
ast::visibility)) {
|
||||||
let crate_data = cstore::get_crate_data(cstore, def_id.crate);
|
let crate_data = cstore::get_crate_data(cstore, def_id.crate);
|
||||||
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
|
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
|
||||||
cstore::get_crate_data(cstore, cnum)
|
cstore::get_crate_data(cstore, cnum)
|
||||||
@ -68,7 +70,8 @@ pub fn each_child_of_item(cstore: @mut cstore::CStore,
|
|||||||
pub fn each_top_level_item_of_crate(cstore: @mut cstore::CStore,
|
pub fn each_top_level_item_of_crate(cstore: @mut cstore::CStore,
|
||||||
cnum: ast::CrateNum,
|
cnum: ast::CrateNum,
|
||||||
callback: &fn(decoder::DefLike,
|
callback: &fn(decoder::DefLike,
|
||||||
ast::Ident)) {
|
ast::Ident,
|
||||||
|
ast::visibility)) {
|
||||||
let crate_data = cstore::get_crate_data(cstore, cnum);
|
let crate_data = cstore::get_crate_data(cstore, cnum);
|
||||||
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
|
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
|
||||||
cstore::get_crate_data(cstore, cnum)
|
cstore::get_crate_data(cstore, cnum)
|
||||||
|
@ -96,7 +96,7 @@ fn find_item(item_id: int, items: ebml::Doc) -> ebml::Doc {
|
|||||||
|
|
||||||
// Looks up an item in the given metadata and returns an ebml doc pointing
|
// Looks up an item in the given metadata and returns an ebml doc pointing
|
||||||
// to the item data.
|
// to the item data.
|
||||||
fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
|
pub fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
|
||||||
let items = reader::get_doc(reader::Doc(data), tag_items);
|
let items = reader::get_doc(reader::Doc(data), tag_items);
|
||||||
find_item(item_id, items)
|
find_item(item_id, items)
|
||||||
}
|
}
|
||||||
@ -291,7 +291,7 @@ fn enum_variant_ids(item: ebml::Doc, cdata: Cmd) -> ~[ast::DefId] {
|
|||||||
return ids;
|
return ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_path(item_doc: ebml::Doc) -> ast_map::path {
|
pub fn item_path(item_doc: ebml::Doc) -> ast_map::path {
|
||||||
let path_doc = reader::get_doc(item_doc, tag_path);
|
let path_doc = reader::get_doc(item_doc, tag_path);
|
||||||
|
|
||||||
let len_doc = reader::get_doc(path_doc, tag_path_len);
|
let len_doc = reader::get_doc(path_doc, tag_path_len);
|
||||||
@ -332,7 +332,7 @@ fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::Ident {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn item_to_def_like(item: ebml::Doc, did: ast::DefId, cnum: ast::CrateNum)
|
pub fn item_to_def_like(item: ebml::Doc, did: ast::DefId, cnum: ast::CrateNum)
|
||||||
-> DefLike {
|
-> DefLike {
|
||||||
let fam = item_family(item);
|
let fam = item_family(item);
|
||||||
match fam {
|
match fam {
|
||||||
@ -491,7 +491,7 @@ pub enum DefLike {
|
|||||||
DlField
|
DlField
|
||||||
}
|
}
|
||||||
|
|
||||||
fn def_like_to_def(def_like: DefLike) -> ast::Def {
|
pub fn def_like_to_def(def_like: DefLike) -> ast::Def {
|
||||||
match def_like {
|
match def_like {
|
||||||
DlDef(def) => return def,
|
DlDef(def) => return def,
|
||||||
DlImpl(*) => fail!("found impl in def_like_to_def"),
|
DlImpl(*) => fail!("found impl in def_like_to_def"),
|
||||||
@ -544,7 +544,8 @@ impl<'self> EachItemContext<'self> {
|
|||||||
fn process_item_and_pop_name(&mut self,
|
fn process_item_and_pop_name(&mut self,
|
||||||
doc: ebml::Doc,
|
doc: ebml::Doc,
|
||||||
def_id: ast::DefId,
|
def_id: ast::DefId,
|
||||||
old_len: uint)
|
old_len: uint,
|
||||||
|
vis: ast::visibility)
|
||||||
-> bool {
|
-> bool {
|
||||||
let def_like = item_to_def_like(doc, def_id, self.cdata.cnum);
|
let def_like = item_to_def_like(doc, def_id, self.cdata.cnum);
|
||||||
match def_like {
|
match def_like {
|
||||||
@ -563,8 +564,6 @@ impl<'self> EachItemContext<'self> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let vis = item_visibility(doc);
|
|
||||||
|
|
||||||
let mut continue = (self.callback)(*self.path_builder, def_like, vis);
|
let mut continue = (self.callback)(*self.path_builder, def_like, vis);
|
||||||
|
|
||||||
let family = item_family(doc);
|
let family = item_family(doc);
|
||||||
@ -653,9 +652,12 @@ impl<'self> EachItemContext<'self> {
|
|||||||
self.push_name(token::ident_to_str(&child_name));
|
self.push_name(token::ident_to_str(&child_name));
|
||||||
|
|
||||||
// Process this item.
|
// Process this item.
|
||||||
|
|
||||||
|
let vis = item_visibility(child_item_doc);
|
||||||
continue = self.process_item_and_pop_name(child_item_doc,
|
continue = self.process_item_and_pop_name(child_item_doc,
|
||||||
child_def_id,
|
child_def_id,
|
||||||
old_len);
|
old_len,
|
||||||
|
vis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
@ -701,12 +703,13 @@ impl<'self> EachItemContext<'self> {
|
|||||||
|
|
||||||
// Get the item.
|
// Get the item.
|
||||||
match maybe_find_item(def_id.node, other_crates_items) {
|
match maybe_find_item(def_id.node, other_crates_items) {
|
||||||
None => {}
|
None => { self.pop_name(old_len); }
|
||||||
Some(reexported_item_doc) => {
|
Some(reexported_item_doc) => {
|
||||||
continue = self.process_item_and_pop_name(
|
continue = self.process_item_and_pop_name(
|
||||||
reexported_item_doc,
|
reexported_item_doc,
|
||||||
def_id,
|
def_id,
|
||||||
old_len);
|
old_len,
|
||||||
|
ast::public);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -721,7 +724,8 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
|
|||||||
cdata: Cmd,
|
cdata: Cmd,
|
||||||
item_doc: ebml::Doc,
|
item_doc: ebml::Doc,
|
||||||
get_crate_data: GetCrateDataCb,
|
get_crate_data: GetCrateDataCb,
|
||||||
callback: &fn(DefLike, ast::Ident)) {
|
callback: &fn(DefLike, ast::Ident,
|
||||||
|
ast::visibility)) {
|
||||||
// Iterate over all children.
|
// Iterate over all children.
|
||||||
let _ = do reader::tagged_docs(item_doc, tag_mod_child) |child_info_doc| {
|
let _ = do reader::tagged_docs(item_doc, tag_mod_child) |child_info_doc| {
|
||||||
let child_def_id = reader::with_doc_data(child_info_doc,
|
let child_def_id = reader::with_doc_data(child_info_doc,
|
||||||
@ -746,7 +750,8 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
|
|||||||
let def_like = item_to_def_like(child_item_doc,
|
let def_like = item_to_def_like(child_item_doc,
|
||||||
child_def_id,
|
child_def_id,
|
||||||
cdata.cnum);
|
cdata.cnum);
|
||||||
callback(def_like, child_name);
|
let visibility = item_visibility(child_item_doc);
|
||||||
|
callback(def_like, child_name, visibility);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -788,7 +793,8 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
|
|||||||
impl_method_def_id,
|
impl_method_def_id,
|
||||||
cdata.cnum);
|
cdata.cnum);
|
||||||
callback(static_method_def_like,
|
callback(static_method_def_like,
|
||||||
static_method_name);
|
static_method_name,
|
||||||
|
item_visibility(impl_method_doc));
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -831,7 +837,8 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
|
|||||||
let def_like = item_to_def_like(child_item_doc,
|
let def_like = item_to_def_like(child_item_doc,
|
||||||
child_def_id,
|
child_def_id,
|
||||||
cdata.cnum);
|
cdata.cnum);
|
||||||
callback(def_like, token::str_to_ident(name));
|
callback(def_like, token::str_to_ident(name),
|
||||||
|
item_visibility(child_item_doc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -844,7 +851,7 @@ pub fn each_child_of_item(intr: @ident_interner,
|
|||||||
cdata: Cmd,
|
cdata: Cmd,
|
||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
get_crate_data: GetCrateDataCb,
|
get_crate_data: GetCrateDataCb,
|
||||||
callback: &fn(DefLike, ast::Ident)) {
|
callback: &fn(DefLike, ast::Ident, ast::visibility)) {
|
||||||
// Find the item.
|
// Find the item.
|
||||||
let root_doc = reader::Doc(cdata.data);
|
let root_doc = reader::Doc(cdata.data);
|
||||||
let items = reader::get_doc(root_doc, tag_items);
|
let items = reader::get_doc(root_doc, tag_items);
|
||||||
@ -864,7 +871,8 @@ pub fn each_child_of_item(intr: @ident_interner,
|
|||||||
pub fn each_top_level_item_of_crate(intr: @ident_interner,
|
pub fn each_top_level_item_of_crate(intr: @ident_interner,
|
||||||
cdata: Cmd,
|
cdata: Cmd,
|
||||||
get_crate_data: GetCrateDataCb,
|
get_crate_data: GetCrateDataCb,
|
||||||
callback: &fn(DefLike, ast::Ident)) {
|
callback: &fn(DefLike, ast::Ident,
|
||||||
|
ast::visibility)) {
|
||||||
let root_doc = reader::Doc(cdata.data);
|
let root_doc = reader::Doc(cdata.data);
|
||||||
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
|
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
|
||||||
let crate_items_doc = reader::get_doc(misc_info_doc,
|
let crate_items_doc = reader::get_doc(misc_info_doc,
|
||||||
@ -1161,7 +1169,8 @@ pub fn get_static_methods_if_impl(intr: @ident_interner,
|
|||||||
static_impl_methods.push(StaticMethodInfo {
|
static_impl_methods.push(StaticMethodInfo {
|
||||||
ident: item_name(intr, impl_method_doc),
|
ident: item_name(intr, impl_method_doc),
|
||||||
def_id: item_def_id(impl_method_doc, cdata),
|
def_id: item_def_id(impl_method_doc, cdata),
|
||||||
purity: purity
|
purity: purity,
|
||||||
|
vis: item_visibility(impl_method_doc),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -16,9 +16,9 @@ use metadata::cstore;
|
|||||||
use metadata::decoder;
|
use metadata::decoder;
|
||||||
use metadata::tyencode;
|
use metadata::tyencode;
|
||||||
use middle::ty::{node_id_to_type, lookup_item_type};
|
use middle::ty::{node_id_to_type, lookup_item_type};
|
||||||
|
use middle::astencode;
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use middle::typeck;
|
use middle::typeck;
|
||||||
use middle::astencode;
|
|
||||||
use middle;
|
use middle;
|
||||||
|
|
||||||
use std::hashmap::{HashMap, HashSet};
|
use std::hashmap::{HashMap, HashSet};
|
||||||
@ -58,6 +58,7 @@ pub struct EncodeParams<'self> {
|
|||||||
diag: @mut span_handler,
|
diag: @mut span_handler,
|
||||||
tcx: ty::ctxt,
|
tcx: ty::ctxt,
|
||||||
reexports2: middle::resolve::ExportMap2,
|
reexports2: middle::resolve::ExportMap2,
|
||||||
|
exported_items: @middle::privacy::ExportedItems,
|
||||||
item_symbols: &'self HashMap<ast::NodeId, ~str>,
|
item_symbols: &'self HashMap<ast::NodeId, ~str>,
|
||||||
discrim_symbols: &'self HashMap<ast::NodeId, @str>,
|
discrim_symbols: &'self HashMap<ast::NodeId, @str>,
|
||||||
non_inlineable_statics: &'self HashSet<ast::NodeId>,
|
non_inlineable_statics: &'self HashSet<ast::NodeId>,
|
||||||
@ -88,6 +89,7 @@ pub struct EncodeContext<'self> {
|
|||||||
tcx: ty::ctxt,
|
tcx: ty::ctxt,
|
||||||
stats: @mut Stats,
|
stats: @mut Stats,
|
||||||
reexports2: middle::resolve::ExportMap2,
|
reexports2: middle::resolve::ExportMap2,
|
||||||
|
exported_items: @middle::privacy::ExportedItems,
|
||||||
item_symbols: &'self HashMap<ast::NodeId, ~str>,
|
item_symbols: &'self HashMap<ast::NodeId, ~str>,
|
||||||
discrim_symbols: &'self HashMap<ast::NodeId, @str>,
|
discrim_symbols: &'self HashMap<ast::NodeId, @str>,
|
||||||
non_inlineable_statics: &'self HashSet<ast::NodeId>,
|
non_inlineable_statics: &'self HashSet<ast::NodeId>,
|
||||||
@ -881,7 +883,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||||||
ebml_w: &mut writer::Encoder,
|
ebml_w: &mut writer::Encoder,
|
||||||
item: @item,
|
item: @item,
|
||||||
index: @mut ~[entry<i64>],
|
index: @mut ~[entry<i64>],
|
||||||
path: &[ast_map::path_elt]) {
|
path: &[ast_map::path_elt],
|
||||||
|
vis: ast::visibility) {
|
||||||
let tcx = ecx.tcx;
|
let tcx = ecx.tcx;
|
||||||
|
|
||||||
fn add_to_index_(item: @item, ebml_w: &writer::Encoder,
|
fn add_to_index_(item: @item, ebml_w: &writer::Encoder,
|
||||||
@ -912,6 +915,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||||||
if !ecx.non_inlineable_statics.contains(&item.id) {
|
if !ecx.non_inlineable_statics.contains(&item.id) {
|
||||||
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
|
(ecx.encode_inlined_item)(ecx, ebml_w, path, ii_item(item));
|
||||||
}
|
}
|
||||||
|
encode_visibility(ebml_w, vis);
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
item_fn(_, purity, _, ref generics, _) => {
|
item_fn(_, purity, _, ref generics, _) => {
|
||||||
@ -929,6 +933,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||||||
} else {
|
} else {
|
||||||
encode_symbol(ecx, ebml_w, item.id);
|
encode_symbol(ecx, ebml_w, item.id);
|
||||||
}
|
}
|
||||||
|
encode_visibility(ebml_w, vis);
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
item_mod(ref m) => {
|
item_mod(ref m) => {
|
||||||
@ -955,7 +960,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||||||
ebml_w.wr_str(def_to_str(local_def(foreign_item.id)));
|
ebml_w.wr_str(def_to_str(local_def(foreign_item.id)));
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
|
encode_visibility(ebml_w, vis);
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
item_ty(*) => {
|
item_ty(*) => {
|
||||||
@ -967,6 +972,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||||||
encode_name(ecx, ebml_w, item.ident);
|
encode_name(ecx, ebml_w, item.ident);
|
||||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||||
encode_region_param(ecx, ebml_w, item);
|
encode_region_param(ecx, ebml_w, item);
|
||||||
|
encode_visibility(ebml_w, vis);
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
}
|
}
|
||||||
item_enum(ref enum_definition, ref generics) => {
|
item_enum(ref enum_definition, ref generics) => {
|
||||||
@ -987,6 +993,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||||||
// Encode inherent implementations for this enumeration.
|
// Encode inherent implementations for this enumeration.
|
||||||
encode_inherent_implementations(ecx, ebml_w, def_id);
|
encode_inherent_implementations(ecx, ebml_w, def_id);
|
||||||
|
|
||||||
|
encode_visibility(ebml_w, vis);
|
||||||
ebml_w.end_tag();
|
ebml_w.end_tag();
|
||||||
|
|
||||||
encode_enum_variant_info(ecx,
|
encode_enum_variant_info(ecx,
|
||||||
@ -1018,6 +1025,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
|
|||||||
encode_attributes(ebml_w, item.attrs);
|
encode_attributes(ebml_w, item.attrs);
|
||||||
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
encode_path(ecx, ebml_w, path, ast_map::path_name(item.ident));
|
||||||
encode_region_param(ecx, ebml_w, item);
|
encode_region_param(ecx, ebml_w, item);
|
||||||
|
encode_visibility(ebml_w, vis);
|
||||||
|
|
||||||
/* Encode def_ids for each field and method
|
/* Encode def_ids for each field and method
|
||||||
for methods, write all the stuff get_trait_method
|
for methods, write all the stuff get_trait_method
|
||||||
@ -1264,7 +1272,12 @@ fn my_visit_item(i:@item, items: ast_map::map, ebml_w:&writer::Encoder,
|
|||||||
let mut ebml_w = ebml_w.clone();
|
let mut ebml_w = ebml_w.clone();
|
||||||
// See above
|
// See above
|
||||||
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
||||||
encode_info_for_item(ecx, &mut ebml_w, i, index, *pt);
|
let vis = if ecx.exported_items.contains(&i.id) {
|
||||||
|
ast::public
|
||||||
|
} else {
|
||||||
|
ast::inherited
|
||||||
|
};
|
||||||
|
encode_info_for_item(ecx, &mut ebml_w, i, index, *pt, vis);
|
||||||
}
|
}
|
||||||
_ => fail!("bad item")
|
_ => fail!("bad item")
|
||||||
}
|
}
|
||||||
@ -1727,6 +1740,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
|
|||||||
diag,
|
diag,
|
||||||
tcx,
|
tcx,
|
||||||
reexports2,
|
reexports2,
|
||||||
|
exported_items,
|
||||||
discrim_symbols,
|
discrim_symbols,
|
||||||
cstore,
|
cstore,
|
||||||
encode_inlined_item,
|
encode_inlined_item,
|
||||||
@ -1742,6 +1756,7 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
|
|||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
stats: stats,
|
stats: stats,
|
||||||
reexports2: reexports2,
|
reexports2: reexports2,
|
||||||
|
exported_items: exported_items,
|
||||||
item_symbols: item_symbols,
|
item_symbols: item_symbols,
|
||||||
discrim_symbols: discrim_symbols,
|
discrim_symbols: discrim_symbols,
|
||||||
non_inlineable_statics: non_inlineable_statics,
|
non_inlineable_statics: non_inlineable_statics,
|
||||||
|
@ -150,7 +150,7 @@ fn make_rustpkg_target_lib_path(dir: &Path,
|
|||||||
dir.push_rel(&Path(libdir()).push(target_triple.to_owned()))
|
dir.push_rel(&Path(libdir()).push(target_triple.to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_or_default_sysroot() -> Path {
|
pub fn get_or_default_sysroot() -> Path {
|
||||||
match os::self_exe_path() {
|
match os::self_exe_path() {
|
||||||
option::Some(ref p) => (*p).pop(),
|
option::Some(ref p) => (*p).pop(),
|
||||||
option::None => fail!("can't determine value for sysroot")
|
option::None => fail!("can't determine value for sysroot")
|
||||||
|
@ -9,9 +9,13 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
//! A pass that checks to make sure private fields and methods aren't used
|
//! A pass that checks to make sure private fields and methods aren't used
|
||||||
//! outside their scopes.
|
//! outside their scopes. This pass will also generate a set of exported items
|
||||||
|
//! which are available for use externally when compiled as a library.
|
||||||
|
|
||||||
|
use std::hashmap::HashSet;
|
||||||
|
|
||||||
use metadata::csearch;
|
use metadata::csearch;
|
||||||
|
use middle::resolve::ExportMap2;
|
||||||
use middle::ty::{ty_struct, ty_enum};
|
use middle::ty::{ty_struct, ty_enum};
|
||||||
use middle::ty;
|
use middle::ty;
|
||||||
use middle::typeck::{method_map, method_origin, method_param};
|
use middle::typeck::{method_map, method_origin, method_param};
|
||||||
@ -37,9 +41,23 @@ use syntax::visit;
|
|||||||
use syntax::visit::Visitor;
|
use syntax::visit::Visitor;
|
||||||
use syntax::ast::{_mod,Expr,item,Block,Pat};
|
use syntax::ast::{_mod,Expr,item,Block,Pat};
|
||||||
|
|
||||||
|
// This set is a set of all item nodes which can be used by external crates if
|
||||||
|
// we're building a library. The necessary qualifications for this are that all
|
||||||
|
// items leading down to the current item (excluding an `impl`) must be `pub`.
|
||||||
|
pub type ExportedItems = HashSet<NodeId>;
|
||||||
|
|
||||||
|
type Context<'self> = (&'self method_map, &'self ExportMap2);
|
||||||
|
|
||||||
struct PrivacyVisitor {
|
struct PrivacyVisitor {
|
||||||
tcx: ty::ctxt,
|
tcx: ty::ctxt,
|
||||||
privileged_items: @mut ~[NodeId],
|
privileged_items: @mut ~[NodeId],
|
||||||
|
|
||||||
|
// A set of all items which are re-exported to be used across crates
|
||||||
|
exported_items: ExportedItems,
|
||||||
|
|
||||||
|
// A flag as to whether the current path is public all the way down to the
|
||||||
|
// current point or not
|
||||||
|
path_all_public: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrivacyVisitor {
|
impl PrivacyVisitor {
|
||||||
@ -265,15 +283,20 @@ impl PrivacyVisitor {
|
|||||||
.last()
|
.last()
|
||||||
.identifier)));
|
.identifier)));
|
||||||
}
|
}
|
||||||
} else if csearch::get_item_visibility(self.tcx.sess.cstore,
|
//} else if csearch::get_item_visibility(self.tcx.sess.cstore,
|
||||||
def_id) != public {
|
// def_id) != public {
|
||||||
self.tcx.sess.span_err(span,
|
// self.tcx.sess.span_err(span,
|
||||||
fmt!("function `%s` is private",
|
// fmt!("function `%s` is private",
|
||||||
token::ident_to_str(
|
// token::ident_to_str(
|
||||||
&path.segments
|
// &path.segments
|
||||||
.last()
|
// .last()
|
||||||
.identifier)));
|
// .identifier)));
|
||||||
}
|
}
|
||||||
|
// If this is a function from a non-local crate, then the
|
||||||
|
// privacy check is enforced during resolve. All public items
|
||||||
|
// will be tagged as such in the crate metadata and then usage
|
||||||
|
// of the private items will be blocked during resolve. Hence,
|
||||||
|
// if this isn't from the local crate, nothing to check.
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@ -341,31 +364,78 @@ impl PrivacyVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
|
impl<'self> Visitor<Context<'self>> for PrivacyVisitor {
|
||||||
|
|
||||||
fn visit_mod<'mm>(&mut self, the_module:&_mod, _:Span, _:NodeId,
|
fn visit_mod(&mut self, the_module:&_mod, _:Span, _:NodeId,
|
||||||
method_map:&'mm method_map) {
|
cx: Context<'self>) {
|
||||||
|
|
||||||
let n_added = self.add_privileged_items(the_module.items);
|
let n_added = self.add_privileged_items(the_module.items);
|
||||||
|
|
||||||
visit::walk_mod(self, the_module, method_map);
|
visit::walk_mod(self, the_module, cx);
|
||||||
|
|
||||||
do n_added.times {
|
do n_added.times {
|
||||||
ignore(self.privileged_items.pop());
|
ignore(self.privileged_items.pop());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_item<'mm>(&mut self, item:@item, method_map:&'mm method_map) {
|
fn visit_item(&mut self, item:@item, cx: Context<'self>) {
|
||||||
|
|
||||||
// Do not check privacy inside items with the resolve_unexported
|
// Do not check privacy inside items with the resolve_unexported
|
||||||
// attribute. This is used for the test runner.
|
// attribute. This is used for the test runner.
|
||||||
if !attr::contains_name(item.attrs, "!resolve_unexported") {
|
if attr::contains_name(item.attrs, "!resolve_unexported") {
|
||||||
check_sane_privacy(self.tcx, item);
|
return;
|
||||||
visit::walk_item(self, item, method_map);
|
}
|
||||||
|
|
||||||
|
// Disallow unnecessary visibility qualifiers
|
||||||
|
check_sane_privacy(self.tcx, item);
|
||||||
|
|
||||||
|
// Keep track of whether this item is available for export or not.
|
||||||
|
let orig_all_pub = self.path_all_public;
|
||||||
|
match item.node {
|
||||||
|
// impls/extern blocks do not break the "public chain" because they
|
||||||
|
// cannot have visibility qualifiers on them anyway
|
||||||
|
ast::item_impl(*) | ast::item_foreign_mod(*) => {}
|
||||||
|
|
||||||
|
// Private by default, hence we only retain the "public chain" if
|
||||||
|
// `pub` is explicitly listed.
|
||||||
|
_ => {
|
||||||
|
self.path_all_public = orig_all_pub && item.vis == ast::public;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
debug2!("public path at {}: {}", item.id, self.path_all_public);
|
||||||
|
|
||||||
|
if self.path_all_public {
|
||||||
|
debug2!("all the way public {}", item.id);
|
||||||
|
self.exported_items.insert(item.id);
|
||||||
|
|
||||||
|
// All re-exported items in a module which is public should also be
|
||||||
|
// public (in terms of how they should get encoded)
|
||||||
|
match item.node {
|
||||||
|
ast::item_mod(*) => {
|
||||||
|
let (_, exp_map2) = cx;
|
||||||
|
match exp_map2.find(&item.id) {
|
||||||
|
Some(exports) => {
|
||||||
|
for export in exports.iter() {
|
||||||
|
if export.reexport && is_local(export.def_id) {
|
||||||
|
debug2!("found reexported {:?}", export);
|
||||||
|
let id = export.def_id.node;
|
||||||
|
self.exported_items.insert(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visit::walk_item(self, item, cx);
|
||||||
|
|
||||||
|
self.path_all_public = orig_all_pub;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_block<'mm>(&mut self, block:&Block, method_map:&'mm method_map) {
|
fn visit_block(&mut self, block:&Block, cx: Context<'self>) {
|
||||||
|
|
||||||
// Gather up all the privileged items.
|
// Gather up all the privileged items.
|
||||||
let mut n_added = 0;
|
let mut n_added = 0;
|
||||||
@ -383,7 +453,7 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit::walk_block(self, block, method_map);
|
visit::walk_block(self, block, cx);
|
||||||
|
|
||||||
do n_added.times {
|
do n_added.times {
|
||||||
ignore(self.privileged_items.pop());
|
ignore(self.privileged_items.pop());
|
||||||
@ -391,8 +461,8 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_expr<'mm>(&mut self, expr:@Expr, method_map:&'mm method_map) {
|
fn visit_expr(&mut self, expr:@Expr, cx: Context<'self>) {
|
||||||
|
let (method_map, _) = cx;
|
||||||
match expr.node {
|
match expr.node {
|
||||||
ExprField(base, ident, _) => {
|
ExprField(base, ident, _) => {
|
||||||
// Method calls are now a special syntactic form,
|
// Method calls are now a special syntactic form,
|
||||||
@ -499,11 +569,11 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit::walk_expr(self, expr, method_map);
|
visit::walk_expr(self, expr, cx);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_pat<'mm>(&mut self, pattern:@Pat, method_map:&'mm method_map) {
|
fn visit_pat(&mut self, pattern:@Pat, cx: Context<'self>) {
|
||||||
|
|
||||||
match pattern.node {
|
match pattern.node {
|
||||||
PatStruct(_, ref fields, _) => {
|
PatStruct(_, ref fields, _) => {
|
||||||
@ -550,20 +620,24 @@ impl<'self> Visitor<&'self method_map> for PrivacyVisitor {
|
|||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
visit::walk_pat(self, pattern, method_map);
|
visit::walk_pat(self, pattern, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check_crate<'mm>(tcx: ty::ctxt,
|
pub fn check_crate(tcx: ty::ctxt,
|
||||||
method_map: &'mm method_map,
|
method_map: &method_map,
|
||||||
crate: &ast::Crate) {
|
exp_map2: &ExportMap2,
|
||||||
|
crate: &ast::Crate) -> ExportedItems {
|
||||||
let privileged_items = @mut ~[];
|
let privileged_items = @mut ~[];
|
||||||
|
|
||||||
let mut visitor = PrivacyVisitor {
|
let mut visitor = PrivacyVisitor {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
privileged_items: privileged_items,
|
privileged_items: privileged_items,
|
||||||
|
exported_items: HashSet::new(),
|
||||||
|
path_all_public: true, // start out as public
|
||||||
};
|
};
|
||||||
visit::walk_crate(&mut visitor, crate, method_map);
|
visit::walk_crate(&mut visitor, crate, (method_map, exp_map2));
|
||||||
|
return visitor.exported_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Validates all of the visibility qualifers placed on the item given. This
|
/// Validates all of the visibility qualifers placed on the item given. This
|
||||||
@ -571,17 +645,45 @@ pub fn check_crate<'mm>(tcx: ty::ctxt,
|
|||||||
/// anything. In theory these qualifiers wouldn't parse, but that may happen
|
/// anything. In theory these qualifiers wouldn't parse, but that may happen
|
||||||
/// later on down the road...
|
/// later on down the road...
|
||||||
fn check_sane_privacy(tcx: ty::ctxt, item: @ast::item) {
|
fn check_sane_privacy(tcx: ty::ctxt, item: @ast::item) {
|
||||||
|
let check_inherited = |sp: Span, vis: ast::visibility, note: &str| {
|
||||||
|
if vis != ast::inherited {
|
||||||
|
tcx.sess.span_err(sp, "unnecessary visibility qualifier");
|
||||||
|
if note.len() > 0 {
|
||||||
|
tcx.sess.span_note(sp, note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let check_not_priv = |sp: Span, vis: ast::visibility, note: &str| {
|
||||||
|
if vis == ast::private {
|
||||||
|
tcx.sess.span_err(sp, "unnecessary `priv` qualifier");
|
||||||
|
if note.len() > 0 {
|
||||||
|
tcx.sess.span_note(sp, note);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
match item.node {
|
match item.node {
|
||||||
// implementations of traits don't need visibility qualifiers because
|
// implementations of traits don't need visibility qualifiers because
|
||||||
// that's controlled by having the trait in scope.
|
// that's controlled by having the trait in scope.
|
||||||
ast::item_impl(_, Some(*), _, ref methods) => {
|
ast::item_impl(_, Some(*), _, ref methods) => {
|
||||||
|
check_inherited(item.span, item.vis,
|
||||||
|
"visibility qualifiers have no effect on trait impls");
|
||||||
for m in methods.iter() {
|
for m in methods.iter() {
|
||||||
match m.vis {
|
check_inherited(m.span, m.vis, "");
|
||||||
ast::private | ast::public => {
|
}
|
||||||
tcx.sess.span_err(m.span, "unnecessary visibility")
|
}
|
||||||
}
|
|
||||||
ast::inherited => {}
|
ast::item_impl(_, _, _, ref methods) => {
|
||||||
}
|
check_inherited(item.span, item.vis,
|
||||||
|
"place qualifiers on individual methods instead");
|
||||||
|
for i in methods.iter() {
|
||||||
|
check_not_priv(i.span, i.vis, "functions are private by default");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ast::item_foreign_mod(ref fm) => {
|
||||||
|
check_inherited(item.span, item.vis,
|
||||||
|
"place qualifiers on individual functions instead");
|
||||||
|
for i in fm.items.iter() {
|
||||||
|
check_not_priv(i.span, i.vis, "functions are private by default");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -624,22 +726,18 @@ fn check_sane_privacy(tcx: ty::ctxt, item: @ast::item) {
|
|||||||
for m in methods.iter() {
|
for m in methods.iter() {
|
||||||
match *m {
|
match *m {
|
||||||
ast::provided(ref m) => {
|
ast::provided(ref m) => {
|
||||||
match m.vis {
|
check_inherited(m.span, m.vis,
|
||||||
ast::private | ast::public => {
|
"unnecessary visibility");
|
||||||
tcx.sess.span_err(m.span, "unnecessary \
|
|
||||||
visibility");
|
|
||||||
}
|
|
||||||
ast::inherited => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// this is warned about in the parser
|
|
||||||
ast::required(*) => {}
|
ast::required(*) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ast::item_impl(*) | ast::item_static(*) | ast::item_foreign_mod(*) |
|
ast::item_static(*) |
|
||||||
ast::item_fn(*) | ast::item_mod(*) | ast::item_ty(*) |
|
ast::item_fn(*) | ast::item_mod(*) | ast::item_ty(*) |
|
||||||
ast::item_mac(*) => {}
|
ast::item_mac(*) => {
|
||||||
|
check_not_priv(item.span, item.vis, "items are private by default");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1661,6 +1661,9 @@ impl Resolver {
|
|||||||
ident: Ident,
|
ident: Ident,
|
||||||
new_parent: ReducedGraphParent) {
|
new_parent: ReducedGraphParent) {
|
||||||
let privacy = visibility_to_privacy(visibility);
|
let privacy = visibility_to_privacy(visibility);
|
||||||
|
debug!("(building reduced graph for \
|
||||||
|
external crate) building external def, priv %?",
|
||||||
|
privacy);
|
||||||
match def {
|
match def {
|
||||||
DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
|
DefMod(def_id) | DefForeignMod(def_id) | DefStruct(def_id) |
|
||||||
DefTy(def_id) => {
|
DefTy(def_id) => {
|
||||||
@ -1788,7 +1791,8 @@ impl Resolver {
|
|||||||
fn build_reduced_graph_for_external_crate_def(@mut self,
|
fn build_reduced_graph_for_external_crate_def(@mut self,
|
||||||
root: @mut Module,
|
root: @mut Module,
|
||||||
def_like: DefLike,
|
def_like: DefLike,
|
||||||
ident: Ident) {
|
ident: Ident,
|
||||||
|
visibility: visibility) {
|
||||||
match def_like {
|
match def_like {
|
||||||
DlDef(def) => {
|
DlDef(def) => {
|
||||||
// Add the new child item, if necessary.
|
// Add the new child item, if necessary.
|
||||||
@ -1798,11 +1802,12 @@ impl Resolver {
|
|||||||
// eagerly.
|
// eagerly.
|
||||||
do csearch::each_child_of_item(self.session.cstore,
|
do csearch::each_child_of_item(self.session.cstore,
|
||||||
def_id)
|
def_id)
|
||||||
|def_like, child_ident| {
|
|def_like, child_ident, vis| {
|
||||||
self.build_reduced_graph_for_external_crate_def(
|
self.build_reduced_graph_for_external_crate_def(
|
||||||
root,
|
root,
|
||||||
def_like,
|
def_like,
|
||||||
child_ident)
|
child_ident,
|
||||||
|
vis)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@ -1813,7 +1818,7 @@ impl Resolver {
|
|||||||
dummy_sp());
|
dummy_sp());
|
||||||
|
|
||||||
self.handle_external_def(def,
|
self.handle_external_def(def,
|
||||||
public,
|
visibility,
|
||||||
child_name_bindings,
|
child_name_bindings,
|
||||||
self.session.str_of(ident),
|
self.session.str_of(ident),
|
||||||
ident,
|
ident,
|
||||||
@ -1897,10 +1902,11 @@ impl Resolver {
|
|||||||
let def = DefFn(
|
let def = DefFn(
|
||||||
static_method_info.def_id,
|
static_method_info.def_id,
|
||||||
static_method_info.purity);
|
static_method_info.purity);
|
||||||
|
|
||||||
|
let p = visibility_to_privacy(
|
||||||
|
static_method_info.vis);
|
||||||
method_name_bindings.define_value(
|
method_name_bindings.define_value(
|
||||||
Public,
|
p, def, dummy_sp());
|
||||||
def,
|
|
||||||
dummy_sp());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1931,12 +1937,13 @@ impl Resolver {
|
|||||||
};
|
};
|
||||||
|
|
||||||
do csearch::each_child_of_item(self.session.cstore, def_id)
|
do csearch::each_child_of_item(self.session.cstore, def_id)
|
||||||
|def_like, child_ident| {
|
|def_like, child_ident, visibility| {
|
||||||
debug!("(populating external module) ... found ident: %s",
|
debug!("(populating external module) ... found ident: %s",
|
||||||
token::ident_to_str(&child_ident));
|
token::ident_to_str(&child_ident));
|
||||||
self.build_reduced_graph_for_external_crate_def(module,
|
self.build_reduced_graph_for_external_crate_def(module,
|
||||||
def_like,
|
def_like,
|
||||||
child_ident)
|
child_ident,
|
||||||
|
visibility)
|
||||||
}
|
}
|
||||||
module.populated = true
|
module.populated = true
|
||||||
}
|
}
|
||||||
@ -1956,10 +1963,11 @@ impl Resolver {
|
|||||||
root: @mut Module) {
|
root: @mut Module) {
|
||||||
do csearch::each_top_level_item_of_crate(self.session.cstore,
|
do csearch::each_top_level_item_of_crate(self.session.cstore,
|
||||||
root.def_id.unwrap().crate)
|
root.def_id.unwrap().crate)
|
||||||
|def_like, ident| {
|
|def_like, ident, visibility| {
|
||||||
self.build_reduced_graph_for_external_crate_def(root,
|
self.build_reduced_graph_for_external_crate_def(root,
|
||||||
def_like,
|
def_like,
|
||||||
ident)
|
ident,
|
||||||
|
visibility)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3008,6 +3008,7 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::encode_
|
|||||||
diag: diag,
|
diag: diag,
|
||||||
tcx: cx.tcx,
|
tcx: cx.tcx,
|
||||||
reexports2: cx.exp_map2,
|
reexports2: cx.exp_map2,
|
||||||
|
exported_items: cx.exported_items,
|
||||||
item_symbols: item_symbols,
|
item_symbols: item_symbols,
|
||||||
discrim_symbols: discrim_symbols,
|
discrim_symbols: discrim_symbols,
|
||||||
non_inlineable_statics: &cx.non_inlineable_statics,
|
non_inlineable_statics: &cx.non_inlineable_statics,
|
||||||
@ -3101,6 +3102,7 @@ pub fn trans_crate(sess: session::Session,
|
|||||||
llmod_id,
|
llmod_id,
|
||||||
analysis.ty_cx,
|
analysis.ty_cx,
|
||||||
analysis.exp_map2,
|
analysis.exp_map2,
|
||||||
|
analysis.exported_items,
|
||||||
analysis.maps,
|
analysis.maps,
|
||||||
symbol_hasher,
|
symbol_hasher,
|
||||||
link_meta,
|
link_meta,
|
||||||
|
@ -16,6 +16,7 @@ use lib::llvm::{llvm, TargetData, TypeNames};
|
|||||||
use lib::llvm::mk_target_data;
|
use lib::llvm::mk_target_data;
|
||||||
use metadata::common::LinkMeta;
|
use metadata::common::LinkMeta;
|
||||||
use middle::astencode;
|
use middle::astencode;
|
||||||
|
use middle::privacy;
|
||||||
use middle::resolve;
|
use middle::resolve;
|
||||||
use middle::trans::adt;
|
use middle::trans::adt;
|
||||||
use middle::trans::base;
|
use middle::trans::base;
|
||||||
@ -49,6 +50,7 @@ pub struct CrateContext {
|
|||||||
intrinsics: HashMap<&'static str, ValueRef>,
|
intrinsics: HashMap<&'static str, ValueRef>,
|
||||||
item_vals: HashMap<ast::NodeId, ValueRef>,
|
item_vals: HashMap<ast::NodeId, ValueRef>,
|
||||||
exp_map2: resolve::ExportMap2,
|
exp_map2: resolve::ExportMap2,
|
||||||
|
exported_items: @privacy::ExportedItems,
|
||||||
reachable: @mut HashSet<ast::NodeId>,
|
reachable: @mut HashSet<ast::NodeId>,
|
||||||
item_symbols: HashMap<ast::NodeId, ~str>,
|
item_symbols: HashMap<ast::NodeId, ~str>,
|
||||||
link_meta: LinkMeta,
|
link_meta: LinkMeta,
|
||||||
@ -127,6 +129,7 @@ impl CrateContext {
|
|||||||
name: &str,
|
name: &str,
|
||||||
tcx: ty::ctxt,
|
tcx: ty::ctxt,
|
||||||
emap2: resolve::ExportMap2,
|
emap2: resolve::ExportMap2,
|
||||||
|
exported_items: @privacy::ExportedItems,
|
||||||
maps: astencode::Maps,
|
maps: astencode::Maps,
|
||||||
symbol_hasher: hash::State,
|
symbol_hasher: hash::State,
|
||||||
link_meta: LinkMeta,
|
link_meta: LinkMeta,
|
||||||
@ -187,6 +190,7 @@ impl CrateContext {
|
|||||||
intrinsics: intrinsics,
|
intrinsics: intrinsics,
|
||||||
item_vals: HashMap::new(),
|
item_vals: HashMap::new(),
|
||||||
exp_map2: emap2,
|
exp_map2: emap2,
|
||||||
|
exported_items: exported_items,
|
||||||
reachable: reachable,
|
reachable: reachable,
|
||||||
item_symbols: HashMap::new(),
|
item_symbols: HashMap::new(),
|
||||||
link_meta: link_meta,
|
link_meta: link_meta,
|
||||||
|
@ -702,7 +702,7 @@ impl AstBuilder for @ExtCtxt {
|
|||||||
attrs: attrs,
|
attrs: attrs,
|
||||||
id: ast::DUMMY_NODE_ID,
|
id: ast::DUMMY_NODE_ID,
|
||||||
node: node,
|
node: node,
|
||||||
vis: ast::public,
|
vis: ast::inherited,
|
||||||
span: span }
|
span: span }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,6 @@ pub enum ObsoleteSyntax {
|
|||||||
ObsoleteImplSyntax,
|
ObsoleteImplSyntax,
|
||||||
ObsoleteMutOwnedPointer,
|
ObsoleteMutOwnedPointer,
|
||||||
ObsoleteMutVector,
|
ObsoleteMutVector,
|
||||||
ObsoleteImplVisibility,
|
|
||||||
ObsoleteRecordType,
|
ObsoleteRecordType,
|
||||||
ObsoleteRecordPattern,
|
ObsoleteRecordPattern,
|
||||||
ObsoletePostFnTySigil,
|
ObsoletePostFnTySigil,
|
||||||
@ -60,9 +59,7 @@ pub enum ObsoleteSyntax {
|
|||||||
ObsoleteNamedExternModule,
|
ObsoleteNamedExternModule,
|
||||||
ObsoleteMultipleLocalDecl,
|
ObsoleteMultipleLocalDecl,
|
||||||
ObsoleteMutWithMultipleBindings,
|
ObsoleteMutWithMultipleBindings,
|
||||||
ObsoleteExternVisibility,
|
|
||||||
ObsoleteUnsafeExternFn,
|
ObsoleteUnsafeExternFn,
|
||||||
ObsoletePrivVisibility,
|
|
||||||
ObsoleteTraitFuncVisibility,
|
ObsoleteTraitFuncVisibility,
|
||||||
ObsoleteConstPointer,
|
ObsoleteConstPointer,
|
||||||
}
|
}
|
||||||
@ -161,11 +158,6 @@ impl ParserObsoleteMethods for Parser {
|
|||||||
in a mutable location, like a mutable local variable or an \
|
in a mutable location, like a mutable local variable or an \
|
||||||
`@mut` box"
|
`@mut` box"
|
||||||
),
|
),
|
||||||
ObsoleteImplVisibility => (
|
|
||||||
"visibility-qualified implementation",
|
|
||||||
"`pub` or `priv` goes on individual functions; remove the \
|
|
||||||
`pub` or `priv`"
|
|
||||||
),
|
|
||||||
ObsoleteRecordType => (
|
ObsoleteRecordType => (
|
||||||
"structural record type",
|
"structural record type",
|
||||||
"use a structure instead"
|
"use a structure instead"
|
||||||
@ -233,20 +225,11 @@ impl ParserObsoleteMethods for Parser {
|
|||||||
"use multiple local declarations instead of e.g. `let mut \
|
"use multiple local declarations instead of e.g. `let mut \
|
||||||
(x, y) = ...`."
|
(x, y) = ...`."
|
||||||
),
|
),
|
||||||
ObsoleteExternVisibility => (
|
|
||||||
"`pub extern` or `priv extern`",
|
|
||||||
"place the `pub` or `priv` on the individual external items \
|
|
||||||
instead"
|
|
||||||
),
|
|
||||||
ObsoleteUnsafeExternFn => (
|
ObsoleteUnsafeExternFn => (
|
||||||
"unsafe external function",
|
"unsafe external function",
|
||||||
"external functions are always unsafe; remove the `unsafe` \
|
"external functions are always unsafe; remove the `unsafe` \
|
||||||
keyword"
|
keyword"
|
||||||
),
|
),
|
||||||
ObsoletePrivVisibility => (
|
|
||||||
"`priv` not necessary",
|
|
||||||
"an item without a visibility qualifier is private by default"
|
|
||||||
),
|
|
||||||
ObsoleteTraitFuncVisibility => (
|
ObsoleteTraitFuncVisibility => (
|
||||||
"visibility not necessary",
|
"visibility not necessary",
|
||||||
"trait functions inherit the visibility of the trait itself"
|
"trait functions inherit the visibility of the trait itself"
|
||||||
|
@ -922,7 +922,7 @@ impl Parser {
|
|||||||
let attrs = p.parse_outer_attributes();
|
let attrs = p.parse_outer_attributes();
|
||||||
let lo = p.span.lo;
|
let lo = p.span.lo;
|
||||||
|
|
||||||
let vis = p.parse_non_priv_visibility();
|
let vis = p.parse_visibility();
|
||||||
let pur = p.parse_fn_purity();
|
let pur = p.parse_fn_purity();
|
||||||
// NB: at the moment, trait methods are public by default; this
|
// NB: at the moment, trait methods are public by default; this
|
||||||
// could change.
|
// could change.
|
||||||
@ -3753,7 +3753,7 @@ impl Parser {
|
|||||||
let attrs = self.parse_outer_attributes();
|
let attrs = self.parse_outer_attributes();
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
|
|
||||||
let visa = self.parse_non_priv_visibility();
|
let visa = self.parse_visibility();
|
||||||
let pur = self.parse_fn_purity();
|
let pur = self.parse_fn_purity();
|
||||||
let ident = self.parse_ident();
|
let ident = self.parse_ident();
|
||||||
let generics = self.parse_generics();
|
let generics = self.parse_generics();
|
||||||
@ -3801,7 +3801,7 @@ impl Parser {
|
|||||||
// Parses two variants (with the region/type params always optional):
|
// Parses two variants (with the region/type params always optional):
|
||||||
// impl<T> Foo { ... }
|
// impl<T> Foo { ... }
|
||||||
// impl<T> ToStr for ~[T] { ... }
|
// impl<T> ToStr for ~[T] { ... }
|
||||||
fn parse_item_impl(&self, visibility: ast::visibility) -> item_info {
|
fn parse_item_impl(&self) -> item_info {
|
||||||
// First, parse type parameters if necessary.
|
// First, parse type parameters if necessary.
|
||||||
let generics = self.parse_generics();
|
let generics = self.parse_generics();
|
||||||
|
|
||||||
@ -3846,11 +3846,6 @@ impl Parser {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
// Do not allow visibility to be specified.
|
|
||||||
if visibility != ast::inherited {
|
|
||||||
self.obsolete(*self.span, ObsoleteImplVisibility);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut meths = ~[];
|
let mut meths = ~[];
|
||||||
if !self.eat(&token::SEMI) {
|
if !self.eat(&token::SEMI) {
|
||||||
self.expect(&token::LBRACE);
|
self.expect(&token::LBRACE);
|
||||||
@ -4012,18 +4007,6 @@ impl Parser {
|
|||||||
else { inherited }
|
else { inherited }
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse visibility, but emits an obsolete error if it's private
|
|
||||||
fn parse_non_priv_visibility(&self) -> visibility {
|
|
||||||
match self.parse_visibility() {
|
|
||||||
public => public,
|
|
||||||
inherited => inherited,
|
|
||||||
private => {
|
|
||||||
self.obsolete(*self.last_span, ObsoletePrivVisibility);
|
|
||||||
inherited
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_staticness(&self) -> bool {
|
fn parse_staticness(&self) -> bool {
|
||||||
if self.eat_keyword(keywords::Static) {
|
if self.eat_keyword(keywords::Static) {
|
||||||
self.obsolete(*self.last_span, ObsoleteStaticMethod);
|
self.obsolete(*self.last_span, ObsoleteStaticMethod);
|
||||||
@ -4216,7 +4199,7 @@ impl Parser {
|
|||||||
// parse a function declaration from a foreign module
|
// parse a function declaration from a foreign module
|
||||||
fn parse_item_foreign_fn(&self, attrs: ~[Attribute]) -> @foreign_item {
|
fn parse_item_foreign_fn(&self, attrs: ~[Attribute]) -> @foreign_item {
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
let vis = self.parse_non_priv_visibility();
|
let vis = self.parse_visibility();
|
||||||
|
|
||||||
// Parse obsolete purity.
|
// Parse obsolete purity.
|
||||||
let purity = self.parse_fn_purity();
|
let purity = self.parse_fn_purity();
|
||||||
@ -4352,11 +4335,6 @@ impl Parser {
|
|||||||
self.obsolete(*self.last_span, ObsoleteNamedExternModule);
|
self.obsolete(*self.last_span, ObsoleteNamedExternModule);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not allow visibility to be specified.
|
|
||||||
if visibility != ast::inherited {
|
|
||||||
self.obsolete(*self.last_span, ObsoleteExternVisibility);
|
|
||||||
}
|
|
||||||
|
|
||||||
let abis = opt_abis.unwrap_or(AbiSet::C());
|
let abis = opt_abis.unwrap_or(AbiSet::C());
|
||||||
|
|
||||||
let (inner, next) = self.parse_inner_attrs_and_next();
|
let (inner, next) = self.parse_inner_attrs_and_next();
|
||||||
@ -4367,7 +4345,7 @@ impl Parser {
|
|||||||
self.last_span.hi,
|
self.last_span.hi,
|
||||||
ident,
|
ident,
|
||||||
item_foreign_mod(m),
|
item_foreign_mod(m),
|
||||||
public,
|
visibility,
|
||||||
maybe_append(attrs, Some(inner))));
|
maybe_append(attrs, Some(inner))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4614,7 +4592,7 @@ impl Parser {
|
|||||||
|
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
|
|
||||||
let visibility = self.parse_non_priv_visibility();
|
let visibility = self.parse_visibility();
|
||||||
|
|
||||||
// must be a view item:
|
// must be a view item:
|
||||||
if self.eat_keyword(keywords::Use) {
|
if self.eat_keyword(keywords::Use) {
|
||||||
@ -4722,8 +4700,7 @@ impl Parser {
|
|||||||
}
|
}
|
||||||
if self.eat_keyword(keywords::Impl) {
|
if self.eat_keyword(keywords::Impl) {
|
||||||
// IMPL ITEM
|
// IMPL ITEM
|
||||||
let (ident, item_, extra_attrs) =
|
let (ident, item_, extra_attrs) = self.parse_item_impl();
|
||||||
self.parse_item_impl(visibility);
|
|
||||||
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
return iovi_item(self.mk_item(lo, self.last_span.hi, ident, item_,
|
||||||
visibility,
|
visibility,
|
||||||
maybe_append(attrs, extra_attrs)));
|
maybe_append(attrs, extra_attrs)));
|
||||||
@ -4746,7 +4723,7 @@ impl Parser {
|
|||||||
maybe_whole!(iovi self, nt_item);
|
maybe_whole!(iovi self, nt_item);
|
||||||
let lo = self.span.lo;
|
let lo = self.span.lo;
|
||||||
|
|
||||||
let visibility = self.parse_non_priv_visibility();
|
let visibility = self.parse_visibility();
|
||||||
|
|
||||||
if (self.is_keyword(keywords::Const) || self.is_keyword(keywords::Static)) {
|
if (self.is_keyword(keywords::Const) || self.is_keyword(keywords::Static)) {
|
||||||
// FOREIGN CONST ITEM
|
// FOREIGN CONST ITEM
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
#[link (name = "issue2378a")];
|
#[link (name = "issue2378a")];
|
||||||
#[crate_type = "lib"];
|
#[crate_type = "lib"];
|
||||||
|
|
||||||
enum maybe<T> { just(T), nothing }
|
pub enum maybe<T> { just(T), nothing }
|
||||||
|
|
||||||
impl <T:Clone> Index<uint,T> for maybe<T> {
|
impl <T:Clone> Index<uint,T> for maybe<T> {
|
||||||
fn index(&self, _idx: &uint) -> T {
|
fn index(&self, _idx: &uint) -> T {
|
||||||
|
@ -15,7 +15,7 @@ extern mod issue2378a;
|
|||||||
|
|
||||||
use issue2378a::maybe;
|
use issue2378a::maybe;
|
||||||
|
|
||||||
struct two_maybes<T> {a: maybe<T>, b: maybe<T>}
|
pub struct two_maybes<T> {a: maybe<T>, b: maybe<T>}
|
||||||
|
|
||||||
impl<T:Clone> Index<uint,(T,T)> for two_maybes<T> {
|
impl<T:Clone> Index<uint,(T,T)> for two_maybes<T> {
|
||||||
fn index(&self, idx: &uint) -> (T, T) {
|
fn index(&self, idx: &uint) -> (T, T) {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
// original problem
|
// original problem
|
||||||
fn foo<T>() -> int {
|
pub fn foo<T>() -> int {
|
||||||
{
|
{
|
||||||
static foo: int = 2;
|
static foo: int = 2;
|
||||||
foo
|
foo
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#[packed]
|
#[packed]
|
||||||
struct S {
|
pub struct S {
|
||||||
a: u8,
|
a: u8,
|
||||||
b: u32
|
b: u32
|
||||||
}
|
}
|
||||||
|
57
src/test/auxiliary/static_priv_by_default.rs
Normal file
57
src/test/auxiliary/static_priv_by_default.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2013 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.
|
||||||
|
|
||||||
|
#[crate_type = "lib"];
|
||||||
|
#[no_std];
|
||||||
|
|
||||||
|
static private: int = 0;
|
||||||
|
pub static public: int = 0;
|
||||||
|
|
||||||
|
pub struct A(());
|
||||||
|
|
||||||
|
impl A {
|
||||||
|
fn foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod foo {
|
||||||
|
pub static a: int = 0;
|
||||||
|
pub fn b() {}
|
||||||
|
pub struct c;
|
||||||
|
pub enum d {}
|
||||||
|
|
||||||
|
pub struct A(());
|
||||||
|
|
||||||
|
impl A {
|
||||||
|
fn foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// these are public so the parent can reexport them.
|
||||||
|
pub static reexported_a: int = 0;
|
||||||
|
pub fn reexported_b() {}
|
||||||
|
pub struct reexported_c;
|
||||||
|
pub enum reexported_d {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod bar {
|
||||||
|
pub use e = foo::reexported_a;
|
||||||
|
pub use f = foo::reexported_b;
|
||||||
|
pub use g = foo::reexported_c;
|
||||||
|
pub use h = foo::reexported_d;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static a: int = 0;
|
||||||
|
pub fn b() {}
|
||||||
|
pub struct c;
|
||||||
|
pub enum d {}
|
||||||
|
|
||||||
|
static i: int = 0;
|
||||||
|
fn j() {}
|
||||||
|
struct k;
|
||||||
|
enum l {}
|
@ -54,9 +54,9 @@ extern mod obsolete_name {
|
|||||||
fn bar();
|
fn bar();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern {
|
trait A {
|
||||||
//~^ ERROR obsolete syntax: `pub extern`
|
pub fn foo(); //~ ERROR: visibility not necessary
|
||||||
pub fn bar();
|
pub fn bar(); //~ ERROR: visibility not necessary
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() { }
|
fn main() { }
|
||||||
|
28
src/test/compile-fail/priv-in-bad-locations.rs
Normal file
28
src/test/compile-fail/priv-in-bad-locations.rs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2013 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 extern {
|
||||||
|
//~^ ERROR unnecessary visibility
|
||||||
|
pub fn bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
trait A {
|
||||||
|
fn foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct B;
|
||||||
|
|
||||||
|
pub impl B {} //~ ERROR: unnecessary visibility
|
||||||
|
|
||||||
|
pub impl A for B { //~ ERROR: unnecessary visibility
|
||||||
|
pub fn foo() {} //~ ERROR: unnecessary visibility
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() {}
|
39
src/test/compile-fail/static-priv-by-default.rs
Normal file
39
src/test/compile-fail/static-priv-by-default.rs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2013 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:static_priv_by_default.rs
|
||||||
|
|
||||||
|
#[no_std];
|
||||||
|
|
||||||
|
extern mod static_priv_by_default;
|
||||||
|
|
||||||
|
mod child {
|
||||||
|
pub mod childs_child {
|
||||||
|
static private: int = 0;
|
||||||
|
pub static public: int = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn foo(_: int) {}
|
||||||
|
|
||||||
|
fn full_ref() {
|
||||||
|
foo(static_priv_by_default::private); //~ ERROR: unresolved name
|
||||||
|
foo(static_priv_by_default::public);
|
||||||
|
foo(child::childs_child::private); //~ ERROR: unresolved name
|
||||||
|
foo(child::childs_child::public);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn medium_ref() {
|
||||||
|
use child::childs_child;
|
||||||
|
foo(childs_child::private); //~ ERROR: unresolved name
|
||||||
|
foo(childs_child::public);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
29
src/test/compile-fail/static-priv-by-default2.rs
Normal file
29
src/test/compile-fail/static-priv-by-default2.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2013 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:static_priv_by_default.rs
|
||||||
|
|
||||||
|
extern mod static_priv_by_default;
|
||||||
|
|
||||||
|
mod child {
|
||||||
|
pub mod childs_child {
|
||||||
|
static private: int = 0;
|
||||||
|
pub static public: int = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
use static_priv_by_default::private; //~ ERROR: unresolved import
|
||||||
|
//~^ ERROR: failed to resolve
|
||||||
|
use static_priv_by_default::public;
|
||||||
|
use child::childs_child::private; //~ ERROR: unresolved import
|
||||||
|
//~^ ERROR: failed to resolve
|
||||||
|
use child::childs_child::public;
|
||||||
|
}
|
@ -12,8 +12,3 @@ pub trait E {
|
|||||||
pub fn foo(); //~ ERROR: obsolete syntax
|
pub fn foo(); //~ ERROR: obsolete syntax
|
||||||
}
|
}
|
||||||
trait F { pub fn foo(); } //~ ERROR: obsolete syntax
|
trait F { pub fn foo(); } //~ ERROR: obsolete syntax
|
||||||
|
|
||||||
struct B;
|
|
||||||
impl E for B {
|
|
||||||
priv fn foo() {} //~ ERROR: obsolete syntax
|
|
||||||
}
|
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
|
// Copyright 2013 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.
|
||||||
|
|
||||||
// xfail-fast
|
// xfail-fast
|
||||||
// aux-build:xc_private_method_lib.rs
|
// aux-build:xc_private_method_lib.rs
|
||||||
|
|
||||||
extern mod xc_private_method_lib;
|
extern mod xc_private_method_lib;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// normal method on struct
|
let _ = xc_private_method_lib::Struct::static_meth_struct();
|
||||||
let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct(); //~ ERROR method `meth_struct` is private
|
//~^ ERROR: unresolved name
|
||||||
// static method on struct
|
|
||||||
let _ = xc_private_method_lib::Struct::static_meth_struct(); //~ ERROR method `static_meth_struct` is private
|
|
||||||
|
|
||||||
// normal method on enum
|
let _ = xc_private_method_lib::Enum::static_meth_enum();
|
||||||
let _ = xc_private_method_lib::Variant1(20).meth_enum(); //~ ERROR method `meth_enum` is private
|
//~^ ERROR: unresolved name
|
||||||
// static method on enum
|
|
||||||
let _ = xc_private_method_lib::Enum::static_meth_enum(); //~ ERROR method `static_meth_enum` is private
|
|
||||||
}
|
}
|
||||||
|
20
src/test/compile-fail/xc-private-method2.rs
Normal file
20
src/test/compile-fail/xc-private-method2.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Copyright 2013 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.
|
||||||
|
|
||||||
|
// xfail-fast
|
||||||
|
// aux-build:xc_private_method_lib.rs
|
||||||
|
|
||||||
|
extern mod xc_private_method_lib;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let _ = xc_private_method_lib::Struct{ x: 10 }.meth_struct(); //~ ERROR method `meth_struct` is private
|
||||||
|
|
||||||
|
let _ = xc_private_method_lib::Variant1(20).meth_enum(); //~ ERROR method `meth_enum` is private
|
||||||
|
}
|
57
src/test/compile-fail/xcrate-private-by-default.rs
Normal file
57
src/test/compile-fail/xcrate-private-by-default.rs
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2013 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:static_priv_by_default.rs
|
||||||
|
|
||||||
|
#[allow(unused_imports)];
|
||||||
|
#[no_std];
|
||||||
|
|
||||||
|
extern mod static_priv_by_default;
|
||||||
|
|
||||||
|
fn foo<T>() {}
|
||||||
|
|
||||||
|
#[start]
|
||||||
|
fn main(_: int, _: **u8, _: *u8) -> int {
|
||||||
|
// Actual public items should be public
|
||||||
|
static_priv_by_default::a;
|
||||||
|
static_priv_by_default::b;
|
||||||
|
static_priv_by_default::c;
|
||||||
|
foo::<static_priv_by_default::d>();
|
||||||
|
|
||||||
|
// publicly re-exported items should be available
|
||||||
|
static_priv_by_default::bar::e;
|
||||||
|
static_priv_by_default::bar::f;
|
||||||
|
static_priv_by_default::bar::g;
|
||||||
|
foo::<static_priv_by_default::bar::h>();
|
||||||
|
|
||||||
|
// private items at the top should be inaccessible
|
||||||
|
static_priv_by_default::i;
|
||||||
|
//~^ ERROR: unresolved name
|
||||||
|
static_priv_by_default::j;
|
||||||
|
//~^ ERROR: unresolved name
|
||||||
|
static_priv_by_default::k;
|
||||||
|
//~^ ERROR: unresolved name
|
||||||
|
foo::<static_priv_by_default::l>();
|
||||||
|
//~^ ERROR: use of undeclared type name
|
||||||
|
//~^^ ERROR: use of undeclared type name
|
||||||
|
|
||||||
|
// public items in a private mod should be inaccessible
|
||||||
|
static_priv_by_default::foo::a;
|
||||||
|
//~^ ERROR: unresolved name
|
||||||
|
static_priv_by_default::foo::b;
|
||||||
|
//~^ ERROR: unresolved name
|
||||||
|
static_priv_by_default::foo::c;
|
||||||
|
//~^ ERROR: unresolved name
|
||||||
|
foo::<static_priv_by_default::foo::d>();
|
||||||
|
//~^ ERROR: use of undeclared type name
|
||||||
|
//~^^ ERROR: use of undeclared type name
|
||||||
|
|
||||||
|
3
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user