auto merge of #9735 : alexcrichton/rust/privacy, r=cmr
This is the culmination and attempted resolution of #8215. The commits have many more details about implementation details and the consequences of this refinement. I'll point out specific locations which may be possible causes for alarm. In general, I have been very happy with how things have turned out. I'm a little sad that I couldn't remove privacy from resolve as much as I did, but I blame glob imports (although in theory even some of this can be mitigated as well).
This commit is contained in:
commit
6ddd011ce8
165
doc/rust.md
165
doc/rust.md
@ -1501,6 +1501,171 @@ is `extern "abi" fn(A1, ..., An) -> R`,
|
||||
where `A1...An` are the declared types of its arguments
|
||||
and `R` is the decalred return type.
|
||||
|
||||
## Visibility and Privacy
|
||||
|
||||
These two terms are often used interchangeably, and what they are attempting to
|
||||
convey is the answer to the question "Can this item be used at this location?"
|
||||
|
||||
Rust's name resolution operates on a global hierarchy of namespaces. Each level
|
||||
in the hierarchy can be thought of as some item. The items are one of those
|
||||
mentioned above, but also include external crates. Declaring or defining a new
|
||||
module can be thought of as inserting a new tree into the hierarchy at the
|
||||
location of the definition.
|
||||
|
||||
To control whether interfaces can be used across modules, Rust checks each use
|
||||
of an item to see whether it should be allowed or not. This is where privacy
|
||||
warnings are generated, or otherwise "you used a private item of another module
|
||||
and weren't allowed to."
|
||||
|
||||
By default, everything in rust is *private*, with two exceptions. The first
|
||||
exception is that struct fields are public by default (but the struct itself is
|
||||
still private by default), and the remaining exception is that enum variants in
|
||||
a `pub` enum are the default visibility of the enum container itself.. You are
|
||||
allowed to alter this default visibility with the `pub` keyword (or `priv`
|
||||
keyword for struct fields and enum variants). When an item is declared as `pub`,
|
||||
it can be thought of as being accessible to the outside world. For example:
|
||||
|
||||
~~~
|
||||
// Declare a private struct
|
||||
struct Foo;
|
||||
|
||||
// Declare a public struct with a private field
|
||||
pub struct Bar {
|
||||
priv field: int
|
||||
}
|
||||
|
||||
// Declare a public enum with public and private variants
|
||||
pub enum State {
|
||||
PubliclyAccessibleState,
|
||||
priv PrivatelyAccessibleState
|
||||
}
|
||||
~~~
|
||||
|
||||
With the notion of an item being either public or private, Rust allows item
|
||||
accesses in two cases:
|
||||
|
||||
1. If an item is public, then it can be used externally through any of its
|
||||
public ancestors.
|
||||
2. If an item is private, it may be accessed by the current module and its
|
||||
descendants.
|
||||
|
||||
These two cases are surprisingly powerful for creating module hierarchies
|
||||
exposing public APIs while hiding internal implementation details. To help
|
||||
explain, here's a few use cases and what they would entail.
|
||||
|
||||
* A library developer needs to expose functionality to crates which link against
|
||||
their library. As a consequence of the first case, this means that anything
|
||||
which is usable externally must be `pub` from the root down to the destination
|
||||
item. Any private item in the chain will disallow external accesses.
|
||||
|
||||
* A crate needs a global available "helper module" to itself, but it doesn't
|
||||
want to expose the helper module as a public API. To accomplish this, the root
|
||||
of the crate's hierarchy would have a private module which then internally has
|
||||
a "public api". Because the entire crate is an ancestor of the root, then the
|
||||
entire local crate can access this private module through the second case.
|
||||
|
||||
* When writing unit tests for a module, it's often a common idiom to have an
|
||||
immediate child of the module to-be-tested named `mod test`. This module could
|
||||
access any items of the parent module through the second case, meaning that
|
||||
internal implementation details could also be seamlessly tested from the child
|
||||
module.
|
||||
|
||||
In the second case, it mentions that a private item "can be accessed" by the
|
||||
current module and its descendants, but the exact meaning of accessing an item
|
||||
depends on what the item is. Accessing a module, for example, would mean looking
|
||||
inside of it (to import more items). On the other hand, accessing a function
|
||||
would mean that it is invoked.
|
||||
|
||||
Here's an example of a program which exemplifies the three cases outlined above.
|
||||
|
||||
~~~
|
||||
// This module is private, meaning that no external crate can access this
|
||||
// module. Because it is private at the root of this current crate, however, any
|
||||
// module in the crate may access any publicly visible item in this module.
|
||||
mod crate_helper_module {
|
||||
|
||||
// This function can be used by anything in the current crate
|
||||
pub fn crate_helper() {}
|
||||
|
||||
// This function *cannot* be used by anything else in the crate. It is not
|
||||
// publicly visible outside of the `crate_helper_module`, so only this
|
||||
// current module and its descendants may access it.
|
||||
fn implementation_detail() {}
|
||||
}
|
||||
|
||||
// This function is "public to the root" meaning that it's available to external
|
||||
// crates linking against this one.
|
||||
pub fn public_api() {}
|
||||
|
||||
// Similarly to 'public_api', this module is public so external crates may look
|
||||
// inside of it.
|
||||
pub mod submodule {
|
||||
use crate_helper_module;
|
||||
|
||||
pub fn my_method() {
|
||||
// Any item in the local crate may invoke the helper module's public
|
||||
// interface through a combination of the two rules above.
|
||||
crate_helper_module::crate_helper();
|
||||
}
|
||||
|
||||
// This function is hidden to any module which is not a descendant of
|
||||
// `submodule`
|
||||
fn my_implementation() {}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
|
||||
#[test]
|
||||
fn test_my_implementation() {
|
||||
// Because this module is a descendant of `submodule`, it's allowed
|
||||
// to access private items inside of `submodule` without a privacy
|
||||
// violation.
|
||||
super::my_implementation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# fn main() {}
|
||||
~~~
|
||||
|
||||
For a rust program to pass the privacy checking pass, all paths must be valid
|
||||
accesses given the two rules above. This includes all use statements,
|
||||
expressions, types, etc.
|
||||
|
||||
### Re-exporting and Visibility
|
||||
|
||||
Rust allows publicly re-exporting items through a `pub use` directive. Because
|
||||
this is a public directive, this allows the item to be used in the current
|
||||
module through the rules above. It essentially allows public access into the
|
||||
re-exported item. For example, this program is valid:
|
||||
|
||||
~~~
|
||||
pub use api = self::implementation;
|
||||
|
||||
mod implementation {
|
||||
pub fn f() {}
|
||||
}
|
||||
|
||||
# fn main() {}
|
||||
~~~
|
||||
|
||||
This means that any external crate referencing `implementation::f` would receive
|
||||
a privacy violation, while the path `api::f` would be allowed.
|
||||
|
||||
When re-exporting a private item, it can be thought of as allowing the "privacy
|
||||
chain" being short-circuited through the reexport instead of passing through the
|
||||
namespace hierarchy as it normally would.
|
||||
|
||||
### Glob imports and Visibility
|
||||
|
||||
Currently glob imports are considered an "experimental" language feature. For
|
||||
sanity purpose along with helping the implementation, glob imports will only
|
||||
import public items from their destination, not private items.
|
||||
|
||||
> **Note:** This is subject to change, glob exports may be removed entirely or
|
||||
> they could possibly import private items for a privacy error to later be
|
||||
> issued if the item is used.
|
||||
|
||||
## Attributes
|
||||
|
||||
~~~~~~~~{.ebnf .gram}
|
||||
|
@ -2322,19 +2322,18 @@ fn main() {
|
||||
|
||||
The `::farm::chicken` construct is what we call a 'path'.
|
||||
|
||||
Because it's starting with a `::`, it's also a 'global path',
|
||||
which qualifies an item by its full path in the module hierarchy
|
||||
relative to the crate root.
|
||||
Because it's starting with a `::`, it's also a 'global path', which qualifies
|
||||
an item by its full path in the module hierarchy relative to the crate root.
|
||||
|
||||
If the path were to start with a regular identifier, like `farm::chicken`, it would be
|
||||
a 'local path' instead. We'll get to them later.
|
||||
If the path were to start with a regular identifier, like `farm::chicken`, it
|
||||
would be a 'local path' instead. We'll get to them later.
|
||||
|
||||
Now, if you actually tried to compile this code example, you'll notice
|
||||
that you get a `unresolved name: 'farm::chicken'` error. That's because per default,
|
||||
items (`fn`, `struct`, `static`, `mod`, ...) are only visible inside the module
|
||||
they are defined in.
|
||||
Now, if you actually tried to compile this code example, you'll notice that you
|
||||
get a `function 'chicken' is private` error. That's because by default, items
|
||||
(`fn`, `struct`, `static`, `mod`, ...) are private.
|
||||
|
||||
To make them visible outside their containing modules, you need to mark them _public_ with `pub`:
|
||||
To make them visible outside their containing modules, you need to mark them
|
||||
_public_ with `pub`:
|
||||
|
||||
~~~~
|
||||
mod farm {
|
||||
@ -2356,7 +2355,8 @@ Rust doesn't support encapsulation: both struct fields and methods can
|
||||
be private. But this encapsulation is at the module level, not the
|
||||
struct level.
|
||||
|
||||
For convenience, fields are _public_ by default, and can be made _private_ with the `priv` keyword:
|
||||
For convenience, fields are _public_ by default, and can be made _private_ with
|
||||
the `priv` keyword:
|
||||
|
||||
~~~
|
||||
mod farm {
|
||||
@ -2393,7 +2393,8 @@ fn main() {
|
||||
# fn make_me_a_chicken() -> farm::Chicken { 0 }
|
||||
~~~
|
||||
|
||||
> ***Note:*** Visibility rules are currently buggy and not fully defined, you might have to add or remove `pub` along a path until it works.
|
||||
Exact details and specifications about visibility rules can be found in the Rust
|
||||
manual.
|
||||
|
||||
## Files and modules
|
||||
|
||||
|
@ -40,7 +40,7 @@ pub trait Deque<T> : Mutable {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod bench {
|
||||
pub mod bench {
|
||||
use std::container::MutableMap;
|
||||
use std::{vec, rand};
|
||||
use std::rand::Rng;
|
||||
|
@ -346,7 +346,7 @@ impl <T: FixedBuffer> StandardPadding for T {
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
pub mod test {
|
||||
use std::rand::{IsaacRng, Rng};
|
||||
use std::vec;
|
||||
|
||||
|
@ -101,7 +101,8 @@ pub trait Stats {
|
||||
|
||||
/// Extracted collection of all the summary statistics of a sample set.
|
||||
#[deriving(Clone, Eq)]
|
||||
struct Summary {
|
||||
#[allow(missing_doc)]
|
||||
pub struct Summary {
|
||||
sum: f64,
|
||||
min: f64,
|
||||
max: f64,
|
||||
|
@ -199,7 +199,6 @@ pub fn phase_2_configure_and_expand(sess: Session,
|
||||
|
||||
pub struct CrateAnalysis {
|
||||
exp_map2: middle::resolve::ExportMap2,
|
||||
exported_items: @middle::privacy::ExportedItems,
|
||||
ty_cx: ty::ctxt,
|
||||
maps: astencode::Maps,
|
||||
reachable: @mut HashSet<ast::NodeId>
|
||||
@ -229,7 +228,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
||||
let middle::resolve::CrateMap {
|
||||
def_map: def_map,
|
||||
exp_map2: exp_map2,
|
||||
trait_map: trait_map
|
||||
trait_map: trait_map,
|
||||
external_exports: external_exports,
|
||||
last_private_map: last_private_map
|
||||
} =
|
||||
time(time_passes, "resolution", (), |_|
|
||||
middle::resolve::resolve_crate(sess, lang_items, crate));
|
||||
@ -261,9 +262,10 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
||||
middle::check_const::check_crate(sess, crate, ast_map, def_map,
|
||||
method_map, ty_cx));
|
||||
|
||||
let exported_items =
|
||||
time(time_passes, "privacy checking", (), |_|
|
||||
middle::privacy::check_crate(ty_cx, &method_map, &exp_map2, crate));
|
||||
let maps = (external_exports, last_private_map);
|
||||
time(time_passes, "privacy checking", maps, |(a, b)|
|
||||
middle::privacy::check_crate(ty_cx, &method_map, &exp_map2,
|
||||
a, b, crate));
|
||||
|
||||
time(time_passes, "effect checking", (), |_|
|
||||
middle::effect::check_crate(ty_cx, method_map, crate));
|
||||
@ -305,7 +307,6 @@ pub fn phase_3_run_analysis_passes(sess: Session,
|
||||
|
||||
CrateAnalysis {
|
||||
exp_map2: exp_map2,
|
||||
exported_items: @exported_items,
|
||||
ty_cx: ty_cx,
|
||||
maps: astencode::Maps {
|
||||
root_map: root_map,
|
||||
|
@ -837,8 +837,9 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
|
||||
let def_like = item_to_def_like(child_item_doc,
|
||||
child_def_id,
|
||||
cdata.cnum);
|
||||
callback(def_like, token::str_to_ident(name),
|
||||
item_visibility(child_item_doc));
|
||||
// These items have a public visibility because they're part of
|
||||
// a public re-export.
|
||||
callback(def_like, token::str_to_ident(name), ast::public);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,6 @@ pub struct EncodeParams<'self> {
|
||||
diag: @mut span_handler,
|
||||
tcx: ty::ctxt,
|
||||
reexports2: middle::resolve::ExportMap2,
|
||||
exported_items: @middle::privacy::ExportedItems,
|
||||
item_symbols: &'self HashMap<ast::NodeId, ~str>,
|
||||
discrim_symbols: &'self HashMap<ast::NodeId, @str>,
|
||||
non_inlineable_statics: &'self HashSet<ast::NodeId>,
|
||||
@ -89,7 +88,6 @@ pub struct EncodeContext<'self> {
|
||||
tcx: ty::ctxt,
|
||||
stats: @mut Stats,
|
||||
reexports2: middle::resolve::ExportMap2,
|
||||
exported_items: @middle::privacy::ExportedItems,
|
||||
item_symbols: &'self HashMap<ast::NodeId, ~str>,
|
||||
discrim_symbols: &'self HashMap<ast::NodeId, @str>,
|
||||
non_inlineable_statics: &'self HashSet<ast::NodeId>,
|
||||
@ -625,6 +623,7 @@ fn encode_info_for_mod(ecx: &EncodeContext,
|
||||
}
|
||||
|
||||
encode_path(ecx, ebml_w, path, ast_map::path_mod(name));
|
||||
encode_visibility(ebml_w, vis);
|
||||
|
||||
// Encode the reexports of this module, if this module is public.
|
||||
if vis == public {
|
||||
@ -1277,12 +1276,7 @@ fn my_visit_item(i:@item, items: ast_map::map, ebml_w:&writer::Encoder,
|
||||
let mut ebml_w = ebml_w.clone();
|
||||
// See above
|
||||
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
|
||||
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);
|
||||
encode_info_for_item(ecx, &mut ebml_w, i, index, *pt, i.vis);
|
||||
}
|
||||
_ => fail2!("bad item")
|
||||
}
|
||||
@ -1628,7 +1622,7 @@ impl<'self> Visitor<()> for ImplVisitor<'self> {
|
||||
|
||||
// Load eagerly if this is an implementation of the Drop trait
|
||||
// or if the trait is not defined in this crate.
|
||||
if def_id == self.ecx.tcx.lang_items.drop_trait().unwrap() ||
|
||||
if Some(def_id) == self.ecx.tcx.lang_items.drop_trait() ||
|
||||
def_id.crate != LOCAL_CRATE {
|
||||
self.ebml_w.start_tag(tag_impls_impl);
|
||||
encode_def_id(self.ebml_w, local_def(item.id));
|
||||
@ -1744,7 +1738,6 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
|
||||
diag,
|
||||
tcx,
|
||||
reexports2,
|
||||
exported_items,
|
||||
discrim_symbols,
|
||||
cstore,
|
||||
encode_inlined_item,
|
||||
@ -1760,7 +1753,6 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
|
||||
tcx: tcx,
|
||||
stats: stats,
|
||||
reexports2: reexports2,
|
||||
exported_items: exported_items,
|
||||
item_symbols: item_symbols,
|
||||
discrim_symbols: discrim_symbols,
|
||||
non_inlineable_statics: non_inlineable_statics,
|
||||
|
@ -31,8 +31,8 @@ use syntax::ast_util::id_range;
|
||||
use syntax::codemap::Span;
|
||||
use syntax::print::pprust;
|
||||
use syntax::visit;
|
||||
use syntax::visit::Visitor;
|
||||
use syntax::ast::{Expr, fn_kind, fn_decl, Block, NodeId, Stmt, Pat, Local};
|
||||
use syntax::visit::{Visitor, fn_kind};
|
||||
use syntax::ast::{Expr, fn_decl, Block, NodeId, Stmt, Pat, Local};
|
||||
|
||||
mod lifetime;
|
||||
mod restrictions;
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -3034,7 +3034,6 @@ pub fn crate_ctxt_to_encode_parms<'r>(cx: &'r CrateContext, ie: encoder::encode_
|
||||
diag: diag,
|
||||
tcx: cx.tcx,
|
||||
reexports2: cx.exp_map2,
|
||||
exported_items: cx.exported_items,
|
||||
item_symbols: item_symbols,
|
||||
discrim_symbols: discrim_symbols,
|
||||
non_inlineable_statics: &cx.non_inlineable_statics,
|
||||
@ -3116,7 +3115,6 @@ pub fn trans_crate(sess: session::Session,
|
||||
llmod_id,
|
||||
analysis.ty_cx,
|
||||
analysis.exp_map2,
|
||||
analysis.exported_items,
|
||||
analysis.maps,
|
||||
symbol_hasher,
|
||||
link_meta,
|
||||
|
@ -16,7 +16,6 @@ use lib::llvm::{llvm, TargetData, TypeNames};
|
||||
use lib::llvm::mk_target_data;
|
||||
use metadata::common::LinkMeta;
|
||||
use middle::astencode;
|
||||
use middle::privacy;
|
||||
use middle::resolve;
|
||||
use middle::trans::adt;
|
||||
use middle::trans::base;
|
||||
@ -49,7 +48,6 @@ pub struct CrateContext {
|
||||
intrinsics: HashMap<&'static str, ValueRef>,
|
||||
item_vals: HashMap<ast::NodeId, ValueRef>,
|
||||
exp_map2: resolve::ExportMap2,
|
||||
exported_items: @privacy::ExportedItems,
|
||||
reachable: @mut HashSet<ast::NodeId>,
|
||||
item_symbols: HashMap<ast::NodeId, ~str>,
|
||||
link_meta: LinkMeta,
|
||||
@ -125,7 +123,6 @@ impl CrateContext {
|
||||
name: &str,
|
||||
tcx: ty::ctxt,
|
||||
emap2: resolve::ExportMap2,
|
||||
exported_items: @privacy::ExportedItems,
|
||||
maps: astencode::Maps,
|
||||
symbol_hasher: hash::State,
|
||||
link_meta: LinkMeta,
|
||||
@ -185,7 +182,6 @@ impl CrateContext {
|
||||
intrinsics: intrinsics,
|
||||
item_vals: HashMap::new(),
|
||||
exp_map2: emap2,
|
||||
exported_items: exported_items,
|
||||
reachable: reachable,
|
||||
item_symbols: HashMap::new(),
|
||||
link_meta: link_meta,
|
||||
|
@ -581,7 +581,7 @@ impl Datum {
|
||||
|
||||
if !header && !ty::type_contents(bcx.tcx(), content_ty).contains_managed() {
|
||||
let ptr = self.to_value_llval(bcx);
|
||||
let ty = type_of(bcx.ccx(), content_ty);
|
||||
let ty = type_of::type_of(bcx.ccx(), content_ty);
|
||||
let body = PointerCast(bcx, ptr, ty.ptr_to());
|
||||
Datum {val: body, ty: content_ty, mode: ByRef(ZeroMem)}
|
||||
} else { // has a header
|
||||
|
@ -1026,7 +1026,7 @@ fn trans_lvalue_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
|
||||
// which may not be equal to the enum's type for
|
||||
// non-C-like enums.
|
||||
let val = base::get_item_val(bcx.ccx(), did.node);
|
||||
let pty = type_of(bcx.ccx(), const_ty).ptr_to();
|
||||
let pty = type_of::type_of(bcx.ccx(), const_ty).ptr_to();
|
||||
PointerCast(bcx, val, pty)
|
||||
} else {
|
||||
{
|
||||
@ -1040,7 +1040,7 @@ fn trans_lvalue_unadjusted(bcx: @mut Block, expr: &ast::Expr) -> DatumBlock {
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let llty = type_of(bcx.ccx(), const_ty);
|
||||
let llty = type_of::type_of(bcx.ccx(), const_ty);
|
||||
let symbol = csearch::get_symbol(
|
||||
bcx.ccx().sess.cstore,
|
||||
did);
|
||||
@ -1396,7 +1396,7 @@ fn trans_unary_datum(bcx: @mut Block,
|
||||
heap: heap) -> DatumBlock {
|
||||
let _icx = push_ctxt("trans_boxed_expr");
|
||||
if heap == heap_exchange {
|
||||
let llty = type_of(bcx.ccx(), contents_ty);
|
||||
let llty = type_of::type_of(bcx.ccx(), contents_ty);
|
||||
let size = llsize_of(bcx.ccx(), llty);
|
||||
let Result { bcx: bcx, val: val } = malloc_raw_dyn(bcx, contents_ty,
|
||||
heap_exchange, size);
|
||||
|
@ -203,7 +203,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext,
|
||||
field: uint,
|
||||
ti: @mut tydesc_info) {
|
||||
let _icx = push_ctxt("lazily_emit_tydesc_glue");
|
||||
let llfnty = Type::glue_fn(type_of::type_of(ccx, ti.ty).ptr_to());
|
||||
let llfnty = Type::glue_fn(type_of(ccx, ti.ty).ptr_to());
|
||||
|
||||
if lazily_emit_simplified_tydesc_glue(ccx, field, ti) {
|
||||
return;
|
||||
@ -345,7 +345,7 @@ pub fn make_visit_glue(bcx: @mut Block, v: ValueRef, t: ty::t) -> @mut Block {
|
||||
bcx.tcx().sess.fatal(s);
|
||||
}
|
||||
};
|
||||
let v = PointerCast(bcx, v, type_of::type_of(bcx.ccx(), object_ty).ptr_to());
|
||||
let v = PointerCast(bcx, v, type_of(bcx.ccx(), object_ty).ptr_to());
|
||||
bcx = reflect::emit_calls_to_trait_visit_ty(bcx, t, v, visitor_trait.def_id);
|
||||
// The visitor is a boxed object and needs to be dropped
|
||||
add_clean(bcx, v, object_ty);
|
||||
|
@ -330,8 +330,8 @@ impl CoherenceChecker {
|
||||
|
||||
let impl_poly_type = ty::lookup_item_type(tcx, impl_id);
|
||||
|
||||
let provided = ty::provided_trait_methods(tcx, trait_ref.def_id);
|
||||
for trait_method in provided.iter() {
|
||||
let prov = ty::provided_trait_methods(tcx, trait_ref.def_id);
|
||||
for trait_method in prov.iter() {
|
||||
// Synthesize an ID.
|
||||
let new_id = tcx.sess.next_node_id();
|
||||
let new_did = local_def(new_id);
|
||||
|
@ -126,7 +126,7 @@ enum Implementor {
|
||||
/// to be a fairly large and expensive structure to clone. Instead this adheres
|
||||
/// to both `Send` and `Freeze` so it may be stored in a `RWArc` instance and
|
||||
/// shared among the various rendering tasks.
|
||||
struct Cache {
|
||||
pub struct Cache {
|
||||
/// Mapping of typaram ids to the name of the type parameter. This is used
|
||||
/// when pretty-printing a type (so pretty printing doesn't have to
|
||||
/// painfully maintain a context like this)
|
||||
|
@ -24,7 +24,7 @@ use utils::*;
|
||||
/// This structure keeps track of the state of the world for the code being
|
||||
/// executed in rusti.
|
||||
#[deriving(Clone)]
|
||||
struct Program {
|
||||
pub struct Program {
|
||||
/// All known local variables
|
||||
local_vars: HashMap<~str, LocalVariable>,
|
||||
/// New variables which will be present (learned from typechecking)
|
||||
|
@ -36,10 +36,10 @@ pub mod c_double_utils {
|
||||
pub fn exp(n: c_double) -> c_double;
|
||||
// rename: for consistency with underscore usage elsewhere
|
||||
#[link_name="expm1"]
|
||||
fn exp_m1(n: c_double) -> c_double;
|
||||
pub fn exp_m1(n: c_double) -> c_double;
|
||||
pub fn exp2(n: c_double) -> c_double;
|
||||
#[link_name="fabs"]
|
||||
fn abs(n: c_double) -> c_double;
|
||||
pub fn abs(n: c_double) -> c_double;
|
||||
// rename: for clarity and consistency with add/sub/mul/div
|
||||
#[link_name="fdim"]
|
||||
pub fn abs_sub(a: c_double, b: c_double) -> c_double;
|
||||
|
@ -335,14 +335,15 @@ mod test {
|
||||
// newtype struct autoderef weirdness
|
||||
#[test]
|
||||
fn test_buffered_stream() {
|
||||
use rt;
|
||||
struct S;
|
||||
|
||||
impl Writer for S {
|
||||
impl rt::io::Writer for S {
|
||||
fn write(&mut self, _: &[u8]) {}
|
||||
fn flush(&mut self) {}
|
||||
}
|
||||
|
||||
impl Reader for S {
|
||||
impl rt::io::Reader for S {
|
||||
fn read(&mut self, _: &mut [u8]) -> Option<uint> { None }
|
||||
fn eof(&mut self) -> bool { true }
|
||||
}
|
||||
|
@ -300,7 +300,8 @@ pub mod comm_adapters;
|
||||
mod extensions;
|
||||
|
||||
/// Non-I/O things needed by the I/O module
|
||||
mod support;
|
||||
// XXX: shouldn this really be pub?
|
||||
pub mod support;
|
||||
|
||||
/// Basic Timer
|
||||
pub mod timer;
|
||||
|
@ -67,14 +67,27 @@ use rt::local::Local;
|
||||
use rt::sched::{Scheduler, Shutdown};
|
||||
use rt::sleeper_list::SleeperList;
|
||||
use rt::task::{Task, SchedTask, GreenTask, Sched};
|
||||
use rt::thread::Thread;
|
||||
use rt::work_queue::WorkQueue;
|
||||
use rt::uv::uvio::UvEventLoop;
|
||||
use unstable::atomics::{AtomicInt, SeqCst};
|
||||
use unstable::sync::UnsafeArc;
|
||||
use vec;
|
||||
use vec::{OwnedVector, MutableVector, ImmutableVector};
|
||||
|
||||
use self::thread::Thread;
|
||||
use self::work_queue::WorkQueue;
|
||||
|
||||
// XXX: these probably shouldn't be public...
|
||||
#[doc(hidden)]
|
||||
pub mod shouldnt_be_public {
|
||||
pub use super::sched::Scheduler;
|
||||
pub use super::kill::KillHandle;
|
||||
pub use super::thread::Thread;
|
||||
pub use super::work_queue::WorkQueue;
|
||||
pub use super::select::SelectInner;
|
||||
pub use super::rtio::EventLoop;
|
||||
pub use super::select::{SelectInner, SelectPortInner};
|
||||
}
|
||||
|
||||
/// The global (exchange) heap.
|
||||
pub mod global_heap;
|
||||
|
||||
|
@ -803,6 +803,12 @@ impl SchedHandle {
|
||||
self.queue.push(msg);
|
||||
self.remote.fire();
|
||||
}
|
||||
pub fn send_task_from_friend(&mut self, friend: ~Task) {
|
||||
self.send(TaskFromFriend(friend));
|
||||
}
|
||||
pub fn send_shutdown(&mut self) {
|
||||
self.send(Shutdown);
|
||||
}
|
||||
}
|
||||
|
||||
struct CleanupJob {
|
||||
|
@ -15,10 +15,8 @@ use iter::{Iterator, DoubleEndedIterator};
|
||||
use option::*;
|
||||
// use either::{Either, Left, Right};
|
||||
// use rt::kill::BlockedTask;
|
||||
use rt::sched::Scheduler;
|
||||
use rt::select::{SelectInner, SelectPortInner};
|
||||
use rt::local::Local;
|
||||
use rt::rtio::EventLoop;
|
||||
use rt::shouldnt_be_public::{EventLoop, Scheduler, SelectInner, SelectPortInner};
|
||||
use task;
|
||||
use unstable::finally::Finally;
|
||||
use vec::{OwnedVector, MutableVector};
|
||||
|
@ -551,7 +551,7 @@ pub fn deschedule() {
|
||||
//! Yield control to the task scheduler
|
||||
|
||||
use rt::local::Local;
|
||||
use rt::sched::Scheduler;
|
||||
use rt::shouldnt_be_public::Scheduler;
|
||||
|
||||
// FIXME(#7544): Optimize this, since we know we won't block.
|
||||
let sched: ~Scheduler = Local::take();
|
||||
@ -1069,7 +1069,7 @@ fn test_try_fail() {
|
||||
|
||||
#[cfg(test)]
|
||||
fn get_sched_id() -> int {
|
||||
do Local::borrow |sched: &mut ::rt::sched::Scheduler| {
|
||||
do Local::borrow |sched: &mut ::rt::shouldnt_be_public::Scheduler| {
|
||||
sched.sched_id() as int
|
||||
}
|
||||
}
|
||||
|
@ -89,11 +89,8 @@ use unstable::sync::Exclusive;
|
||||
use rt::in_green_task_context;
|
||||
use rt::local::Local;
|
||||
use rt::task::{Task, Sched};
|
||||
use rt::kill::KillHandle;
|
||||
use rt::sched::Scheduler;
|
||||
use rt::shouldnt_be_public::{Scheduler, KillHandle, WorkQueue, Thread};
|
||||
use rt::uv::uvio::UvEventLoop;
|
||||
use rt::thread::Thread;
|
||||
use rt::work_queue::WorkQueue;
|
||||
|
||||
#[cfg(test)] use task::default_task_opts;
|
||||
#[cfg(test)] use comm;
|
||||
@ -556,8 +553,6 @@ fn enlist_many(child: &KillHandle, child_arc: &TaskGroupArc,
|
||||
}
|
||||
|
||||
pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
|
||||
use rt::sched::*;
|
||||
|
||||
rtassert!(in_green_task_context());
|
||||
|
||||
let child_data = Cell::new(gen_child_taskgroup(opts.linked, opts.supervised));
|
||||
@ -622,7 +617,7 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
|
||||
let mut new_sched_handle = new_sched.make_handle();
|
||||
|
||||
// Allow the scheduler to exit when the pinned task exits
|
||||
new_sched_handle.send(Shutdown);
|
||||
new_sched_handle.send_shutdown();
|
||||
|
||||
// Pin the new task to the new scheduler
|
||||
let new_task = if opts.watched {
|
||||
@ -660,7 +655,7 @@ pub fn spawn_raw(mut opts: TaskOpts, f: ~fn()) {
|
||||
rtdebug!("enqueing join_task");
|
||||
// Now tell the original scheduler to join with this thread
|
||||
// by scheduling a thread-joining task on the original scheduler
|
||||
orig_sched_handle.send(TaskFromFriend(join_task));
|
||||
orig_sched_handle.send_task_from_friend(join_task);
|
||||
|
||||
// NB: We can't simply send a message from here to another task
|
||||
// because this code isn't running in a task and message passing doesn't
|
||||
|
@ -38,7 +38,7 @@ a normal large stack.
|
||||
*/
|
||||
pub fn run_in_bare_thread(f: ~fn()) {
|
||||
use cell::Cell;
|
||||
use rt::thread::Thread;
|
||||
use rt::shouldnt_be_public::Thread;
|
||||
|
||||
let f_cell = Cell::new(f);
|
||||
let (port, chan) = comm::stream();
|
||||
|
@ -90,10 +90,10 @@ mod tests {
|
||||
use super::*;
|
||||
|
||||
use clone::Clone;
|
||||
use ops::Drop;
|
||||
use option::{None, Some};
|
||||
use either::{Either, Left, Right};
|
||||
use sys::size_of;
|
||||
use kinds::Drop;
|
||||
|
||||
#[test]
|
||||
fn identity_crisis() {
|
||||
|
@ -702,32 +702,6 @@ pub fn struct_def_is_tuple_like(struct_def: &ast::struct_def) -> bool {
|
||||
struct_def.ctor_id.is_some()
|
||||
}
|
||||
|
||||
pub fn visibility_to_privacy(visibility: visibility) -> Privacy {
|
||||
match visibility {
|
||||
public => Public,
|
||||
inherited | private => Private
|
||||
}
|
||||
}
|
||||
|
||||
pub fn variant_visibility_to_privacy(visibility: visibility,
|
||||
enclosing_is_public: bool)
|
||||
-> Privacy {
|
||||
if enclosing_is_public {
|
||||
match visibility {
|
||||
public | inherited => Public,
|
||||
private => Private
|
||||
}
|
||||
} else {
|
||||
visibility_to_privacy(visibility)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Eq)]
|
||||
pub enum Privacy {
|
||||
Private,
|
||||
Public
|
||||
}
|
||||
|
||||
/// Returns true if the given pattern consists solely of an identifier
|
||||
/// and false otherwise.
|
||||
pub fn pat_is_ident(pat: @ast::Pat) -> bool {
|
||||
@ -990,7 +964,7 @@ mod test {
|
||||
use super::*;
|
||||
use std::io;
|
||||
use opt_vec;
|
||||
use std::hash::HashMap;
|
||||
use std::hashmap::HashMap;
|
||||
|
||||
fn ident_to_segment(id : &Ident) -> PathSegment {
|
||||
PathSegment{identifier:id.clone(), lifetime: None, types: opt_vec::Empty}
|
||||
|
@ -1551,7 +1551,8 @@ mod test {
|
||||
let varrefs = @mut ~[];
|
||||
visit::walk_crate(&mut new_path_finder(varrefs), &renamed_ast, ());
|
||||
match varrefs {
|
||||
@[Path{segments:[ref seg],_}] => assert_eq!(mtwt_resolve(seg.identifier),a2_name),
|
||||
@[ast::Path{segments:[ref seg],_}] =>
|
||||
assert_eq!(mtwt_resolve(seg.identifier),a2_name),
|
||||
_ => assert_eq!(0,1)
|
||||
}
|
||||
|
||||
@ -1565,7 +1566,8 @@ mod test {
|
||||
let varrefs = @mut ~[];
|
||||
visit::walk_crate(&mut new_path_finder(varrefs), &double_renamed, ());
|
||||
match varrefs {
|
||||
@[Path{segments:[ref seg],_}] => assert_eq!(mtwt_resolve(seg.identifier),a3_name),
|
||||
@[ast::Path{segments:[ref seg],_}] =>
|
||||
assert_eq!(mtwt_resolve(seg.identifier),a3_name),
|
||||
_ => assert_eq!(0,1)
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,8 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: import
|
||||
|
||||
use m::unexported;
|
||||
//~^ ERROR: is private
|
||||
|
||||
mod m {
|
||||
pub fn exported() { }
|
||||
|
@ -8,12 +8,10 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// error-pattern: unresolved name
|
||||
|
||||
mod foo {
|
||||
pub fn x() { }
|
||||
|
||||
enum y { y1, }
|
||||
}
|
||||
|
||||
fn main() { let z = foo::y1; }
|
||||
fn main() { let z = foo::y1; } //~ ERROR: is private
|
||||
|
47
src/test/compile-fail/glob-resolve1.rs
Normal file
47
src/test/compile-fail/glob-resolve1.rs
Normal file
@ -0,0 +1,47 @@
|
||||
// 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.
|
||||
|
||||
// Make sure that globs only bring in public things.
|
||||
|
||||
#[feature(globs)];
|
||||
|
||||
use bar::*;
|
||||
|
||||
mod bar {
|
||||
use import = self::fpriv;
|
||||
fn fpriv() {}
|
||||
extern {
|
||||
fn epriv();
|
||||
}
|
||||
enum A { A1 }
|
||||
pub enum B { B1 }
|
||||
|
||||
struct C;
|
||||
|
||||
type D = int;
|
||||
}
|
||||
|
||||
fn foo<T>() {}
|
||||
|
||||
fn main() {
|
||||
fpriv(); //~ ERROR: unresolved
|
||||
epriv(); //~ ERROR: unresolved
|
||||
A1; //~ ERROR: unresolved
|
||||
B1;
|
||||
C; //~ ERROR: unresolved
|
||||
import(); //~ ERROR: unresolved
|
||||
|
||||
foo::<A>(); //~ ERROR: undeclared
|
||||
//~^ ERROR: undeclared
|
||||
foo::<C>(); //~ ERROR: undeclared
|
||||
//~^ ERROR: undeclared
|
||||
foo::<D>(); //~ ERROR: undeclared
|
||||
//~^ ERROR: undeclared
|
||||
}
|
@ -8,12 +8,11 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use zoo::{duck, goose}; //~ ERROR failed to resolve import
|
||||
//~^ ERROR unresolved import: found `goose` in `zoo` but it is private
|
||||
use zoo::{duck, goose}; //~ ERROR: variant `goose` is private
|
||||
|
||||
mod zoo {
|
||||
pub enum bird {
|
||||
pub duck,
|
||||
pub duck, //~ ERROR: unnecessary `pub` visibility
|
||||
priv goose
|
||||
}
|
||||
}
|
||||
|
@ -8,13 +8,13 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use zoo::fly; //~ ERROR failed to resolve import
|
||||
//~^ ERROR unresolved import: found `fly` in `zoo` but it is private
|
||||
use zoo::fly; //~ ERROR: function `fly` is private
|
||||
|
||||
mod zoo {
|
||||
type fly = ();
|
||||
fn fly() {}
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
fn main() {
|
||||
fly();
|
||||
}
|
||||
|
@ -8,12 +8,13 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use zoo::fly; //~ ERROR failed to resolve import
|
||||
//~^ ERROR unresolved import: found `fly` in `zoo` but it is private
|
||||
use zoo::fly; //~ ERROR: function `fly` is private
|
||||
|
||||
mod zoo {
|
||||
fn fly() {}
|
||||
}
|
||||
|
||||
|
||||
fn main() {}
|
||||
fn main() {
|
||||
fly();
|
||||
}
|
||||
|
39
src/test/compile-fail/issue-4366-2.rs
Normal file
39
src/test/compile-fail/issue-4366-2.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.
|
||||
|
||||
#[feature(globs)];
|
||||
|
||||
// ensures that 'use foo:*' doesn't import non-public item
|
||||
|
||||
use m1::*;
|
||||
|
||||
mod foo {
|
||||
pub fn foo() {}
|
||||
}
|
||||
mod a {
|
||||
pub mod b {
|
||||
use foo::foo;
|
||||
type bar = int;
|
||||
}
|
||||
pub mod sub {
|
||||
use a::b::*;
|
||||
fn sub() -> bar { 1 }
|
||||
//~^ ERROR: undeclared type name
|
||||
}
|
||||
}
|
||||
|
||||
mod m1 {
|
||||
fn foo() {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(); //~ ERROR: unresolved name
|
||||
}
|
||||
|
@ -27,8 +27,7 @@ mod a {
|
||||
}
|
||||
pub mod sub {
|
||||
use a::b::*;
|
||||
fn sub() -> bar { foo(); 1 } //~ ERROR: unresolved name `foo`
|
||||
//~^ ERROR: use of undeclared type name `bar`
|
||||
fn sub() -> int { foo(); 1 } //~ ERROR: unresolved name `foo`
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +35,4 @@ mod m1 {
|
||||
fn foo() {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
foo(); //~ ERROR: unresolved name `foo`
|
||||
}
|
||||
fn main() {}
|
||||
|
@ -18,5 +18,5 @@ mod bar {
|
||||
|
||||
fn main() {
|
||||
local_data::set(bar::baz, -10.0);
|
||||
//~^ ERROR unresolved name `bar::baz`
|
||||
//~^ ERROR static `baz` is private
|
||||
}
|
||||
|
169
src/test/compile-fail/privacy1.rs
Normal file
169
src/test/compile-fail/privacy1.rs
Normal file
@ -0,0 +1,169 @@
|
||||
// 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.
|
||||
|
||||
#[feature(globs)];
|
||||
#[no_std]; // makes debugging this test *a lot* easier (during resolve)
|
||||
|
||||
mod bar {
|
||||
// shouln't bring in too much
|
||||
pub use self::glob::*;
|
||||
|
||||
// can't publicly re-export private items
|
||||
pub use self::baz::{foo, bar};
|
||||
//~^ ERROR: function `bar` is private
|
||||
|
||||
pub use self::private::ppriv;
|
||||
//~^ ERROR: function `ppriv` is private
|
||||
|
||||
pub struct A;
|
||||
impl A {
|
||||
pub fn foo() {}
|
||||
fn bar() {}
|
||||
|
||||
pub fn foo2(&self) {}
|
||||
fn bar2(&self) {}
|
||||
}
|
||||
|
||||
pub enum Enum {
|
||||
priv Priv,
|
||||
Pub
|
||||
}
|
||||
|
||||
mod baz {
|
||||
pub struct A;
|
||||
impl A {
|
||||
pub fn foo() {}
|
||||
fn bar() {}
|
||||
|
||||
pub fn foo2(&self) {}
|
||||
fn bar2(&self) {}
|
||||
}
|
||||
|
||||
// both of these are re-exported by `bar`, but only one should be
|
||||
// validly re-exported
|
||||
pub fn foo() {}
|
||||
fn bar() {}
|
||||
}
|
||||
|
||||
extern {
|
||||
fn epriv();
|
||||
pub fn epub();
|
||||
}
|
||||
|
||||
fn test() {
|
||||
self::Priv;
|
||||
self::Pub;
|
||||
unsafe {
|
||||
epriv();
|
||||
epub();
|
||||
}
|
||||
self::baz::A;
|
||||
self::baz::A::foo();
|
||||
self::baz::A::bar(); //~ ERROR: method `bar` is private
|
||||
self::baz::A.foo2();
|
||||
self::baz::A.bar2(); //~ ERROR: method `bar2` is private
|
||||
|
||||
// this used to cause an ICE in privacy traversal.
|
||||
super::gpub();
|
||||
}
|
||||
|
||||
mod glob {
|
||||
pub fn gpub() {}
|
||||
fn gpriv() {}
|
||||
}
|
||||
|
||||
mod private {
|
||||
fn ppriv() {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn gpub() {}
|
||||
|
||||
fn lol() {
|
||||
bar::A;
|
||||
bar::A::foo();
|
||||
bar::A::bar(); //~ ERROR: method `bar` is private
|
||||
bar::A.foo2();
|
||||
bar::A.bar2(); //~ ERROR: method `bar2` is private
|
||||
}
|
||||
|
||||
mod foo {
|
||||
fn test() {
|
||||
::bar::A::foo();
|
||||
::bar::A::bar(); //~ ERROR: method `bar` is private
|
||||
::bar::A.foo2();
|
||||
::bar::A.bar2(); //~ ERROR: method `bar2` is private
|
||||
::bar::baz::A::foo(); //~ ERROR: method `foo` is private
|
||||
::bar::baz::A::bar(); //~ ERROR: method `bar` is private
|
||||
::bar::baz::A.foo2(); //~ ERROR: struct `A` is private
|
||||
::bar::baz::A.bar2(); //~ ERROR: struct `A` is private
|
||||
//~^ ERROR: method `bar2` is private
|
||||
::lol();
|
||||
|
||||
::bar::Priv; //~ ERROR: variant `Priv` is private
|
||||
::bar::Pub;
|
||||
|
||||
unsafe {
|
||||
::bar::epriv(); //~ ERROR: function `epriv` is private
|
||||
::bar::epub();
|
||||
}
|
||||
|
||||
::bar::foo();
|
||||
::bar::bar();
|
||||
|
||||
::bar::gpub();
|
||||
|
||||
::bar::baz::foo(); //~ ERROR: function `foo` is private
|
||||
::bar::baz::bar(); //~ ERROR: function `bar` is private
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
use bar::baz::{foo, bar};
|
||||
//~^ ERROR: function `foo` is private
|
||||
//~^^ ERROR: function `bar` is private
|
||||
foo();
|
||||
bar();
|
||||
}
|
||||
|
||||
fn test3() {
|
||||
use bar::baz;
|
||||
//~^ ERROR: module `baz` is private
|
||||
}
|
||||
|
||||
fn test4() {
|
||||
use bar::{foo, bar};
|
||||
foo();
|
||||
bar();
|
||||
}
|
||||
|
||||
fn test5() {
|
||||
use bar;
|
||||
bar::foo();
|
||||
bar::bar();
|
||||
}
|
||||
}
|
||||
|
||||
pub mod mytest {
|
||||
// Even though the inner `A` struct is a publicly exported item (usable from
|
||||
// external crates through `foo::foo`, it should not be accessible through
|
||||
// its definition path (which has the private `i` module).
|
||||
use self::foo::foo;
|
||||
use self::foo::i::A; //~ ERROR: type `A` is private
|
||||
|
||||
pub mod foo {
|
||||
pub use foo = self::i::A;
|
||||
|
||||
mod i {
|
||||
pub struct A;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[start] fn main(_: int, _: **u8) -> int { 3 }
|
38
src/test/compile-fail/privacy2.rs
Normal file
38
src/test/compile-fail/privacy2.rs
Normal file
@ -0,0 +1,38 @@
|
||||
// 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.
|
||||
|
||||
#[feature(globs)];
|
||||
#[no_std]; // makes debugging this test *a lot* easier (during resolve)
|
||||
|
||||
// Test to make sure that globs don't leak in regular `use` statements.
|
||||
|
||||
mod bar {
|
||||
pub use self::glob::*;
|
||||
|
||||
mod glob {
|
||||
use foo;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foo() {}
|
||||
|
||||
fn test1() {
|
||||
use bar::foo; //~ ERROR: unresolved import
|
||||
//~^ ERROR: failed to resolve
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
use bar::glob::foo;
|
||||
//~^ ERROR: there is no
|
||||
//~^^ ERROR: failed to resolve
|
||||
}
|
||||
|
||||
#[start] fn main(_: int, _: **u8) -> int { 3 }
|
||||
|
33
src/test/compile-fail/privacy3.rs
Normal file
33
src/test/compile-fail/privacy3.rs
Normal file
@ -0,0 +1,33 @@
|
||||
// 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.
|
||||
|
||||
#[feature(globs)];
|
||||
#[no_std]; // makes debugging this test *a lot* easier (during resolve)
|
||||
|
||||
// Test to make sure that private items imported through globs remain private
|
||||
// when they're used.
|
||||
|
||||
mod bar {
|
||||
pub use self::glob::*;
|
||||
|
||||
mod glob {
|
||||
fn gpriv() {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foo() {}
|
||||
|
||||
fn test1() {
|
||||
use bar::gpriv; //~ ERROR: unresolved import
|
||||
//~^ ERROR: failed to resolve
|
||||
gpriv();
|
||||
}
|
||||
|
||||
#[start] fn main(_: int, _: **u8) -> int { 3 }
|
32
src/test/compile-fail/privacy4.rs
Normal file
32
src/test/compile-fail/privacy4.rs
Normal file
@ -0,0 +1,32 @@
|
||||
// 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.
|
||||
|
||||
#[feature(globs)];
|
||||
#[no_std]; // makes debugging this test *a lot* easier (during resolve)
|
||||
|
||||
// Test to make sure that private items imported through globs remain private
|
||||
// when they're used.
|
||||
|
||||
mod bar {
|
||||
pub use self::glob::*;
|
||||
|
||||
mod glob {
|
||||
fn gpriv() {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn foo() {}
|
||||
|
||||
fn test2() {
|
||||
use bar::glob::gpriv; //~ ERROR: function `gpriv` is private
|
||||
gpriv();
|
||||
}
|
||||
|
||||
#[start] fn main(_: int, _: **u8) -> int { 3 }
|
@ -13,5 +13,5 @@ mod a {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
a::f(); //~ ERROR unresolved name
|
||||
a::f(); //~ ERROR function `f` is private
|
||||
}
|
||||
|
@ -17,5 +17,5 @@ mod a {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = a::Liege; //~ ERROR unresolved name
|
||||
let x = a::Liege; //~ ERROR variant `Liege` is private
|
||||
}
|
||||
|
@ -24,15 +24,15 @@ mod child {
|
||||
fn foo(_: int) {}
|
||||
|
||||
fn full_ref() {
|
||||
foo(static_priv_by_default::private); //~ ERROR: unresolved name
|
||||
foo(static_priv_by_default::private); //~ ERROR: static `private` is private
|
||||
foo(static_priv_by_default::public);
|
||||
foo(child::childs_child::private); //~ ERROR: unresolved name
|
||||
foo(child::childs_child::private); //~ ERROR: static `private` is private
|
||||
foo(child::childs_child::public);
|
||||
}
|
||||
|
||||
fn medium_ref() {
|
||||
use child::childs_child;
|
||||
foo(childs_child::private); //~ ERROR: unresolved name
|
||||
foo(childs_child::private); //~ ERROR: static `private` is private
|
||||
foo(childs_child::public);
|
||||
}
|
||||
|
||||
|
@ -19,11 +19,22 @@ mod child {
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
fn foo<T>(_: T) {}
|
||||
|
||||
fn test1() {
|
||||
use child::childs_child::private;
|
||||
//~^ ERROR: static `private` is private
|
||||
use child::childs_child::public;
|
||||
|
||||
foo(private);
|
||||
}
|
||||
|
||||
fn test2() {
|
||||
use static_priv_by_default::private;
|
||||
//~^ ERROR: static `private` is private
|
||||
use static_priv_by_default::public;
|
||||
|
||||
foo(private);
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -15,8 +15,8 @@ extern mod xc_private_method_lib;
|
||||
|
||||
fn main() {
|
||||
let _ = xc_private_method_lib::Struct::static_meth_struct();
|
||||
//~^ ERROR: unresolved name
|
||||
//~^ ERROR: method `static_meth_struct` is private
|
||||
|
||||
let _ = xc_private_method_lib::Enum::static_meth_enum();
|
||||
//~^ ERROR: unresolved name
|
||||
//~^ ERROR: method `static_meth_enum` is private
|
||||
}
|
||||
|
@ -10,15 +10,14 @@
|
||||
|
||||
// aux-build:static_priv_by_default.rs
|
||||
|
||||
#[allow(unused_imports)];
|
||||
#[no_std];
|
||||
#[no_std]; // helps if debugging resolve
|
||||
|
||||
extern mod static_priv_by_default;
|
||||
|
||||
fn foo<T>() {}
|
||||
|
||||
#[start]
|
||||
fn main(_: int, _: **u8, _: *u8) -> int {
|
||||
fn main(_: int, _: **u8) -> int {
|
||||
// Actual public items should be public
|
||||
static_priv_by_default::a;
|
||||
static_priv_by_default::b;
|
||||
@ -33,25 +32,23 @@ fn main(_: int, _: **u8, _: *u8) -> int {
|
||||
|
||||
// private items at the top should be inaccessible
|
||||
static_priv_by_default::i;
|
||||
//~^ ERROR: unresolved name
|
||||
//~^ ERROR: static `i` is private
|
||||
static_priv_by_default::j;
|
||||
//~^ ERROR: unresolved name
|
||||
//~^ ERROR: function `j` is private
|
||||
static_priv_by_default::k;
|
||||
//~^ ERROR: unresolved name
|
||||
//~^ ERROR: struct `k` is private
|
||||
foo::<static_priv_by_default::l>();
|
||||
//~^ ERROR: use of undeclared type name
|
||||
//~^^ ERROR: use of undeclared type name
|
||||
//~^ ERROR: type `l` is private
|
||||
|
||||
// public items in a private mod should be inaccessible
|
||||
static_priv_by_default::foo::a;
|
||||
//~^ ERROR: unresolved name
|
||||
//~^ ERROR: static `a` is private
|
||||
static_priv_by_default::foo::b;
|
||||
//~^ ERROR: unresolved name
|
||||
//~^ ERROR: function `b` is private
|
||||
static_priv_by_default::foo::c;
|
||||
//~^ ERROR: unresolved name
|
||||
//~^ ERROR: struct `c` is private
|
||||
foo::<static_priv_by_default::foo::d>();
|
||||
//~^ ERROR: use of undeclared type name
|
||||
//~^^ ERROR: use of undeclared type name
|
||||
//~^ ERROR: type `d` is private
|
||||
|
||||
3
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
// except according to those terms.
|
||||
|
||||
mod foo {
|
||||
mod bar {
|
||||
pub mod bar {
|
||||
pub fn y() { super::super::foo::x(); }
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ mod rustrt1 {
|
||||
#[abi = "cdecl"]
|
||||
#[link_name = "rustrt"]
|
||||
extern {
|
||||
fn rust_get_test_int() -> libc::intptr_t;
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ mod rustrt2 {
|
||||
#[abi = "cdecl"]
|
||||
#[link_name = "rustrt"]
|
||||
extern {
|
||||
fn rust_get_test_int() -> libc::intptr_t;
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ mod rustrt {
|
||||
use std::libc;
|
||||
|
||||
extern {
|
||||
fn rust_get_test_int() -> libc::intptr_t;
|
||||
pub fn rust_get_test_int() -> libc::intptr_t;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
mod rusti {
|
||||
#[abi = "rust-intrinsic"]
|
||||
extern "rust-intrinsic" {
|
||||
fn uninit<T>() -> T;
|
||||
pub fn uninit<T>() -> T;
|
||||
}
|
||||
}
|
||||
pub fn main() {
|
||||
|
@ -17,24 +17,24 @@ extern mod extra;
|
||||
mod rusti {
|
||||
#[abi = "rust-intrinsic"]
|
||||
extern "rust-intrinsic" {
|
||||
fn ctpop8(x: i8) -> i8;
|
||||
fn ctpop16(x: i16) -> i16;
|
||||
fn ctpop32(x: i32) -> i32;
|
||||
fn ctpop64(x: i64) -> i64;
|
||||
pub fn ctpop8(x: i8) -> i8;
|
||||
pub fn ctpop16(x: i16) -> i16;
|
||||
pub fn ctpop32(x: i32) -> i32;
|
||||
pub fn ctpop64(x: i64) -> i64;
|
||||
|
||||
fn ctlz8(x: i8) -> i8;
|
||||
fn ctlz16(x: i16) -> i16;
|
||||
fn ctlz32(x: i32) -> i32;
|
||||
fn ctlz64(x: i64) -> i64;
|
||||
pub fn ctlz8(x: i8) -> i8;
|
||||
pub fn ctlz16(x: i16) -> i16;
|
||||
pub fn ctlz32(x: i32) -> i32;
|
||||
pub fn ctlz64(x: i64) -> i64;
|
||||
|
||||
fn cttz8(x: i8) -> i8;
|
||||
fn cttz16(x: i16) -> i16;
|
||||
fn cttz32(x: i32) -> i32;
|
||||
fn cttz64(x: i64) -> i64;
|
||||
pub fn cttz8(x: i8) -> i8;
|
||||
pub fn cttz16(x: i16) -> i16;
|
||||
pub fn cttz32(x: i32) -> i32;
|
||||
pub fn cttz64(x: i64) -> i64;
|
||||
|
||||
fn bswap16(x: i16) -> i16;
|
||||
fn bswap32(x: i32) -> i32;
|
||||
fn bswap64(x: i64) -> i64;
|
||||
pub fn bswap16(x: i16) -> i16;
|
||||
pub fn bswap32(x: i32) -> i32;
|
||||
pub fn bswap64(x: i64) -> i64;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,4 +8,4 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
mod test;
|
||||
pub mod test;
|
||||
|
29
src/test/run-pass/privacy1.rs
Normal file
29
src/test/run-pass/privacy1.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.
|
||||
|
||||
pub mod test2 {
|
||||
// This used to generate an ICE (make sure that default functions are
|
||||
// parented to their trait to find the first private thing as the trait).
|
||||
|
||||
struct B;
|
||||
trait A { fn foo(&self) {} }
|
||||
impl A for B {}
|
||||
|
||||
mod tests {
|
||||
use super::A;
|
||||
fn foo() {
|
||||
let a = super::B;
|
||||
a.foo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn main() {}
|
@ -46,7 +46,7 @@ mod m {
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod m {
|
||||
pub mod m {
|
||||
pub fn align() -> uint { 8u }
|
||||
pub fn size() -> uint { 16u }
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user