diff --git a/src/libextra/btree.rs b/src/libextra/btree.rs index ee6d7e8f16fd6..791673d75bb37 100644 --- a/src/libextra/btree.rs +++ b/src/libextra/btree.rs @@ -22,10 +22,10 @@ ///number of elements that a given node can contain. #[allow(missing_doc)] pub struct BTree { - root: Node, - len: uint, - lower_bound: uint, - upper_bound: uint + priv root: Node, + priv len: uint, + priv lower_bound: uint, + priv upper_bound: uint } //We would probably want to remove the dependence on the Clone trait in the future. @@ -47,9 +47,9 @@ impl BTree { ///Helper function for clone: returns new BTree with supplied root node, ///length, and lower bound. For use when the length is known already. - pub fn new_with_node_len(n: Node, - length: uint, - lb: uint) -> BTree { + fn new_with_node_len(n: Node, + length: uint, + lb: uint) -> BTree { BTree { root: n, len: length, @@ -590,4 +590,3 @@ mod test_btree { } } - diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 1b98a9af548ae..a54f3110cd63b 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -202,7 +202,8 @@ pub struct TestOpts { logfile: Option } -type OptRes = Result; +/// Result of parsing the options. +pub type OptRes = Result; fn optgroups() -> ~[getopts::groups::OptGroup] { ~[groups::optflag("", "ignored", "Run ignored tests"), @@ -722,7 +723,8 @@ enum TestEvent { TeResult(TestDesc, TestResult), } -type MonitorMsg = (TestDesc, TestResult); +/// The message sent to the test monitor from the individual runners. +pub type MonitorMsg = (TestDesc, TestResult); fn run_tests(opts: &TestOpts, tests: ~[TestDescAndFn], diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index cccca1309f4c3..0f613c07bd934 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -9,6 +9,7 @@ // except according to those terms. #[allow(missing_doc)]; +#[allow(visible_local_types)]; use json; use json::ToJson; diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs index d746d5012c431..63dfcf394c2e3 100644 --- a/src/libgreen/lib.rs +++ b/src/libgreen/lib.rs @@ -166,9 +166,9 @@ pub struct SchedPool { /// keep track of how many tasks are currently running in the pool and then /// sending on a channel once the entire pool has been drained of all tasks. #[deriving(Clone)] -struct TaskState { - cnt: UnsafeArc, - done: SharedChan<()>, +pub struct TaskState { + priv cnt: UnsafeArc, + priv done: SharedChan<()>, } impl SchedPool { diff --git a/src/libgreen/sched.rs b/src/libgreen/sched.rs index 989b8dc31f8a8..5578a70d4c64f 100644 --- a/src/libgreen/sched.rs +++ b/src/libgreen/sched.rs @@ -40,52 +40,52 @@ pub struct Scheduler { /// reawoken on the wrong pool of schedulers. pool_id: uint, /// There are N work queues, one per scheduler. - work_queue: deque::Worker<~GreenTask>, + priv work_queue: deque::Worker<~GreenTask>, /// Work queues for the other schedulers. These are created by /// cloning the core work queues. - work_queues: ~[deque::Stealer<~GreenTask>], + priv work_queues: ~[deque::Stealer<~GreenTask>], /// The queue of incoming messages from other schedulers. /// These are enqueued by SchedHandles after which a remote callback /// is triggered to handle the message. - message_queue: mpsc::Consumer, + priv message_queue: mpsc::Consumer, /// Producer used to clone sched handles from - message_producer: mpsc::Producer, + priv message_producer: mpsc::Producer, /// A shared list of sleeping schedulers. We'll use this to wake /// up schedulers when pushing work onto the work queue. - sleeper_list: SleeperList, + priv sleeper_list: SleeperList, /// Indicates that we have previously pushed a handle onto the /// SleeperList but have not yet received the Wake message. /// Being `true` does not necessarily mean that the scheduler is /// not active since there are multiple event sources that may /// wake the scheduler. It just prevents the scheduler from pushing /// multiple handles onto the sleeper list. - sleepy: bool, + priv sleepy: bool, /// A flag to indicate we've received the shutdown message and should /// no longer try to go to sleep, but exit instead. - no_sleep: bool, + priv no_sleep: bool, stack_pool: StackPool, /// The scheduler runs on a special task. When it is not running /// it is stored here instead of the work queue. - sched_task: Option<~GreenTask>, + priv sched_task: Option<~GreenTask>, /// An action performed after a context switch on behalf of the /// code running before the context switch - cleanup_job: Option, + priv cleanup_job: Option, /// If the scheduler shouldn't run some tasks, a friend to send /// them to. - friend_handle: Option, + priv friend_handle: Option, /// Should this scheduler run any task, or only pinned tasks? - run_anything: bool, + priv run_anything: bool, /// A fast XorShift rng for scheduler use - rng: XorShiftRng, + priv rng: XorShiftRng, /// A togglable idle callback - idle_callback: Option<~PausableIdleCallback>, + priv idle_callback: Option<~PausableIdleCallback>, /// A countdown that starts at a random value and is decremented /// every time a yield check is performed. When it hits 0 a task /// will yield. - yield_check_count: uint, + priv yield_check_count: uint, /// A flag to tell the scheduler loop it needs to do some stealing /// in order to introduce randomness as part of a yield - steal_for_yield: bool, + priv steal_for_yield: bool, /// Bookeeping for the number of tasks which are currently running around /// inside this pool of schedulers task_state: TaskState, diff --git a/src/libnative/io/mod.rs b/src/libnative/io/mod.rs index f3aca7820a505..4cf5ac74478ef 100644 --- a/src/libnative/io/mod.rs +++ b/src/libnative/io/mod.rs @@ -62,7 +62,7 @@ pub mod timer; mod timer_helper; -type IoResult = Result; +pub type IoResult = Result; fn unimpl() -> IoError { IoError { diff --git a/src/libnative/io/timer_timerfd.rs b/src/libnative/io/timer_timerfd.rs index 4912f4f431f1f..d874e3d1ebb62 100644 --- a/src/libnative/io/timer_timerfd.rs +++ b/src/libnative/io/timer_timerfd.rs @@ -45,6 +45,7 @@ pub struct Timer { priv on_worker: bool, } +#[allow(visible_local_types)] pub enum Req { NewTimer(libc::c_int, Chan<()>, bool, imp::itimerspec), RemoveTimer(libc::c_int, Chan<()>), diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 9cc12caa47834..0bd01975aa9e1 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -331,7 +331,7 @@ pub fn phase_3_run_analysis_passes(sess: Session, } time(time_passes, "lint checking", (), |_| - lint::check_crate(ty_cx, method_map, &exported_items, crate)); + lint::check_crate(ty_cx, method_map, &exported_items, &public_items, crate)); CrateAnalysis { exp_map2: exp_map2, diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index f7ee736f144de..f0518df40cede 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -29,6 +29,8 @@ This API is completely unstable and subject to change. #[feature(macro_rules, globs, struct_variant, managed_boxes)]; +#[allow(visible_local_types)]; + extern mod extra; extern mod syntax; diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 7e6db24a4a319..2a43f3b1f6827 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -106,6 +106,8 @@ pub enum Lint { Unstable, Warnings, + + VisibleLocalTypes } pub fn level_to_str(lv: level) -> &'static str { @@ -362,6 +364,13 @@ static lint_table: &'static [(&'static str, LintSpec)] = &[ desc: "unknown crate type found in #[crate_type] directive", default: deny, }), + + ("visible_local_types", + LintSpec { + lint: VisibleLocalTypes, + desc: "non-exported types used in publically visible signatures", + default: warn + }) ]; /* @@ -376,6 +385,15 @@ pub fn get_lint_dict() -> LintDict { return map; } +#[deriving(Eq)] +enum VisibleLocalTypeParent { + VLTNotExported, + VLTStructField, + VLTEnumVariant, + VLTMethod, + VLTFunction, +} + struct Context<'a> { // All known lint modes (string versions) dict: @LintDict, @@ -388,6 +406,8 @@ struct Context<'a> { method_map: typeck::method_map, // Items exported by the crate; used by the missing_doc lint. exported_items: &'a privacy::ExportedItems, + // Items that are public in their modules + public_items: &'a privacy::PublicItems, // The id of the current `ast::StructDef` being walked. cur_struct_def_id: ast::NodeId, // Whether some ancestor of the current node was marked @@ -400,7 +420,14 @@ struct Context<'a> { lint_stack: ~[(Lint, level, LintSource)], // id of the last visited negated expression - negated_expr_id: ast::NodeId + negated_expr_id: ast::NodeId, + + // Whether the "visible type parent" is exported, see the + // check_visible_type_ty function. + visible_local_type_parent: VisibleLocalTypeParent, + // Whether the parent is a `impl` or `trait` that's not visible + // externally (in which case it's fine to use local types) + vlt_parent_is_local_impl_or_trait: bool } impl<'a> Context<'a> { @@ -1312,6 +1339,198 @@ fn check_missing_doc_variant(cx: &Context, v: &ast::Variant) { check_missing_doc_attrs(cx, Some(v.node.id), v.node.attrs, v.span, "a variant"); } + +/// Check to see if an `ast::Path` refers to any types local to this +/// crate (or, possibly, contains in type parameters via the +/// `check_parameters` arg). One can consider local traits to be +/// public with `private_traits_are_public`. +fn ty_path_contains_local_type(cx: &Context, path: &ast::Path, path_id: ast::NodeId, + check_parameters: bool, private_traits_are_public: bool) -> bool { + let def_map = cx.tcx.def_map.borrow(); + let def_id = match def_map.get().find_copy(&path_id) { + // primitives are "globals" + None => { debug!("not in the def_map"); return false } + Some(ast::DefPrimTy(..)) => { debug!("primitive"); return false } + Some(def) => ast_util::def_id_of_def(def), + }; + let id = def_id.node; + + if ast_util::is_local(def_id) && + !cx.exported_items.contains(&id) { + match cx.tcx.items.find(id) { + None => { debug!("not an item"); return false; } + Some(ast_map::NodeItem(item, _)) if private_traits_are_public => { + debug!("checking for trait...") + match item.node { + ast::ItemTrait(..) => { debug!("private trait"); } + _ => { return true } + } + } + _ => return true + } + } + + if check_parameters { + // the foo::bar::Baz part is public, so now we check the type + // parameters. + path.segments.iter().any(|segment| + segment.types.iter().any(|ty| contains_local_type(cx, *ty))) + } else { + false + } +} + +/// Check to see if `ty` contains any reference to a local +/// (non-exported) type. +fn contains_local_type(cx: &Context, ty: &ast::Ty) -> bool { + let fn_decl = |fn_decl: &ast::FnDecl| { + contains_local_type(cx, fn_decl.output) || + fn_decl.inputs.iter().any(|arg| contains_local_type(cx, arg.ty)) + }; + + match ty.node { + ast::TyNil | ast::TyBot => false, + + ast::TyBox(ty) | + ast::TyUniq(ty) | + ast::TyVec(ty) | + ast::TyFixedLengthVec(ty, _) | + ast::TyPtr(ast::MutTy { ty, .. }) | + ast::TyRptr(_, ast::MutTy { ty, .. }) => contains_local_type(cx, ty), + + ast::TyTup(ref types) => types.iter().any(|t| contains_local_type(cx, *t)), + + ast::TyClosure(clsr) => fn_decl(clsr.decl), + ast::TyBareFn(fun) => fn_decl(fun.decl), + + ast::TyPath(ref p, _, id) => ty_path_contains_local_type(cx, p, id, true, false), + + ast::TyInfer => cx.tcx.sess.span_bug(ty.span, "found TyInfer in lint"), + ast::TyTypeof(_) => cx.tcx.sess.span_bug(ty.span, "found TyTypeof in lint"), + } +} + +/// Execute `inside` after examining the provided trait, trait ref or +/// impl for local types, and setting the relevant fields of `cx` +/// appropriately. These fields are restored after `inside` has +/// finished. +fn check_visible_type_trait_impl_bracketed(cx: &mut Context, + trait_id: Option, + trait_ref: Option<&ast::TraitRef>, + impl_ty_details: Option<&ast::Ty>, + inside: |&mut Context| -> T) -> T { + let old = cx.vlt_parent_is_local_impl_or_trait; + + if !cx.vlt_parent_is_local_impl_or_trait { + // `trait ` + match trait_id { + Some(id) => cx.vlt_parent_is_local_impl_or_trait = !cx.public_items.contains(&id), + None => {} + } + } + if !cx.vlt_parent_is_local_impl_or_trait { + // `impl [Trait for] ` + match impl_ty_details { + Some(ty) => cx.vlt_parent_is_local_impl_or_trait = contains_local_type(cx, ty), + None => {} + } + } + if !cx.vlt_parent_is_local_impl_or_trait { + // impl for ...` + match trait_ref { + Some(r) => { + let def_id = ty::trait_ref_to_def_id(cx.tcx, r); + cx.vlt_parent_is_local_impl_or_trait = !cx.public_items.contains(&def_id.node); + } + None => {} + } + } + + let ret = inside(cx); + + cx.vlt_parent_is_local_impl_or_trait = old; + + ret +} + +/// Check if `id` is public, if so, set the appropriate field of `cx` +/// to `parent_type` and then execute `inside` (restoring the old +/// value after). +fn check_visible_type_nodeid_bracketed(cx: &mut Context, + parent_type: VisibleLocalTypeParent, + id: ast::NodeId, inside: |&mut Context| -> T) -> T { + let old = cx.visible_local_type_parent; + if cx.exported_items.contains(&id) { + cx.visible_local_type_parent = parent_type; + } + let ret = inside(cx); + cx.visible_local_type_parent = old; + + ret +} + +/// If `vis` indicates that this needs to be public (i.e. explicitly +/// public or inheriting from a public thing), then set the +/// appropriate field of `cx` to be `parent_type`, execute `inside` +/// and restore the old value afterward. +fn check_visible_type_vis_bracketed(cx: &mut Context, + parent_type: VisibleLocalTypeParent, + vis: ast::Visibility, inside: |&mut Context| -> T) -> T { + let old = cx.visible_local_type_parent; + cx.visible_local_type_parent = match vis { + ast::Public => parent_type, + ast::Inherited if old != VLTNotExported => parent_type, + // no change + ast::Inherited | ast::Private => VLTNotExported, + }; + debug!("visible local type, bracketing: {:?} -> {:?}", old, cx.visible_local_type_parent); + + let ret = inside(cx); + cx.visible_local_type_parent = old; + + ret +} + +/// Explicitly cancel any checks for visible types, then execute +/// `inside`, restoring the old value. +fn check_visible_type_cancel_bracketed(cx: &mut Context, inside: |&mut Context| -> T) -> T { + let old = cx.visible_local_type_parent; + cx.visible_local_type_parent = VLTNotExported; + + let ret = inside(cx); + + cx.visible_local_type_parent = old; + + ret +} + +fn check_visible_type_ty(cx: &Context, ty: &ast::Ty) { + // only need to check things that are inside visible items. + if cx.vlt_parent_is_local_impl_or_trait { + return + } + + let place = match cx.visible_local_type_parent { + // avoid checking inside "private" things + VLTNotExported => return, + VLTFunction => "function signature", + VLTMethod => "method signature", + VLTEnumVariant => "enum variant", + VLTStructField => "struct field", + }; + + match ty.node { + ast::TyPath(ref p, _, path_id) => { + if ty_path_contains_local_type(cx, p, path_id, false, true) { + cx.span_lint(VisibleLocalTypes, ty.span, + format!("non-exported type used in exported {}", place)) + } + } + // no other type of Ty can can be defined in this crate. + _ => {} + } +} + /// Checks for use of items with #[deprecated], #[experimental] and /// #[unstable] (or none of them) attributes. fn check_stability(cx: &Context, e: &ast::Expr) { @@ -1423,7 +1642,22 @@ impl<'a> Visitor<()> for Context<'a> { cx.visit_ids(|v| v.visit_item(it, ())); - visit::walk_item(cx, it, ()); + match it.node { + ast::ItemStruct(..) => { + check_visible_type_nodeid_bracketed(cx, VLTStructField, it.id, + |cx| visit::walk_item(cx, it, ())) + } + ast::ItemImpl(_, ref trait_ref, self_, _) => { + check_visible_type_trait_impl_bracketed(cx, None, + trait_ref.as_ref(), Some(&*self_), + |cx| visit::walk_item(cx, it, ())) + } + ast::ItemTrait(..) => { + check_visible_type_trait_impl_bracketed(cx, Some(it.id), None, None, + |cx| visit::walk_item(cx, it, ())) + } + _ => visit::walk_item(cx, it, ()) + }; }) } @@ -1473,13 +1707,13 @@ impl<'a> Visitor<()> for Context<'a> { check_type_limits(self, e); check_unused_casts(self, e); - visit::walk_expr(self, e, ()); + check_visible_type_cancel_bracketed(self, |cx| visit::walk_expr(cx, e, ())); } fn visit_stmt(&mut self, s: &ast::Stmt, _: ()) { check_path_statement(self, s); - visit::walk_stmt(self, s, ()); + check_visible_type_cancel_bracketed(self, |cx| visit::walk_stmt(cx, s, ())); } fn visit_fn(&mut self, fk: &visit::FnKind, decl: &ast::FnDecl, @@ -1497,10 +1731,10 @@ impl<'a> Visitor<()> for Context<'a> { cx.visit_ids(|v| { v.visit_fn(fk, decl, body, span, id, ()); }); - recurse(cx); + check_visible_type_nodeid_bracketed(cx, VLTMethod, id, |cx| recurse(cx)); }) } - _ => recurse(self), + _ => check_visible_type_nodeid_bracketed(self, VLTFunction, id, recurse), } } @@ -1510,7 +1744,8 @@ impl<'a> Visitor<()> for Context<'a> { check_missing_doc_ty_method(cx, t); check_attrs_usage(cx, t.attrs); - visit::walk_ty_method(cx, t, ()); + check_visible_type_nodeid_bracketed(cx, VLTMethod, t.id, + |cx| visit::walk_ty_method(cx, t, ())); }) } @@ -1522,7 +1757,11 @@ impl<'a> Visitor<()> for Context<'a> { _: ()) { let old_id = self.cur_struct_def_id; self.cur_struct_def_id = id; - visit::walk_struct_def(self, s, i, g, id, ()); + + check_visible_type_nodeid_bracketed( + self, VLTStructField, id, + |cx| visit::walk_struct_def(cx, s, i, g, id, ())); + self.cur_struct_def_id = old_id; } @@ -1531,7 +1770,13 @@ impl<'a> Visitor<()> for Context<'a> { check_missing_doc_struct_field(cx, s); check_attrs_usage(cx, s.node.attrs); - visit::walk_struct_field(cx, s, ()); + match s.node.kind { + ast::NamedField(_, vis) => { + check_visible_type_vis_bracketed(cx, VLTStructField, vis, + |cx| visit::walk_struct_field(cx, s, ())) + } + ast::UnnamedField => visit::walk_struct_field(cx, s, ()), + } }) } @@ -1539,13 +1784,21 @@ impl<'a> Visitor<()> for Context<'a> { self.with_lint_attrs(v.node.attrs, |cx| { check_missing_doc_variant(cx, v); check_attrs_usage(cx, v.node.attrs); - - visit::walk_variant(cx, v, g, ()); + check_visible_type_nodeid_bracketed(cx, VLTEnumVariant, v.node.id, + |cx| visit::walk_variant(cx, v, g, ())); }) } - // FIXME(#10894) should continue recursing - fn visit_ty(&mut self, _t: &ast::Ty, _: ()) {} + fn visit_ty(&mut self, t: &ast::Ty, _: ()) { + check_visible_type_ty(self, t); + + match t.node { + // FIXME(#10894) should continue recursing through fixed + // length vectors + ast::TyFixedLengthVec(ty, _) => self.visit_ty(ty, ()), + _ => visit::walk_ty(self, t, ()) + } + } } impl<'a> IdVisitingOperation for Context<'a> { @@ -1565,6 +1818,7 @@ impl<'a> IdVisitingOperation for Context<'a> { pub fn check_crate(tcx: ty::ctxt, method_map: typeck::method_map, exported_items: &privacy::ExportedItems, + public_items: &privacy::PublicItems, crate: &ast::Crate) { let mut cx = Context { dict: @get_lint_dict(), @@ -1572,10 +1826,14 @@ pub fn check_crate(tcx: ty::ctxt, tcx: tcx, method_map: method_map, exported_items: exported_items, + public_items: public_items, cur_struct_def_id: -1, is_doc_hidden: false, lint_stack: ~[], - negated_expr_id: -1 + negated_expr_id: -1, + + visible_local_type_parent: VLTNotExported, + vlt_parent_is_local_impl_or_trait: false }; // Install default lint levels, followed by the command line levels, and diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index b0a56cb402b5f..8c33bfa56dbb9 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -98,7 +98,7 @@ pub enum ExternalLocation { } /// Different ways an implementor of a trait can be rendered. -enum Implementor { +pub enum Implementor { /// Paths are displayed specially by omitting the `impl XX for` cruft PathType(clean::Type), /// This is the generic representation of an trait implementor, used for diff --git a/src/librustpkg/lib.rs b/src/librustpkg/lib.rs index c9db8af0b8a9c..f69f14b6cd2df 100644 --- a/src/librustpkg/lib.rs +++ b/src/librustpkg/lib.rs @@ -15,6 +15,7 @@ #[crate_type = "dylib"]; #[feature(globs, managed_boxes)]; +#[allow(visible_local_types)]; extern mod extra; extern mod rustc; diff --git a/src/librustuv/addrinfo.rs b/src/librustuv/addrinfo.rs index aa4dda786e3c6..77d5f0018450a 100644 --- a/src/librustuv/addrinfo.rs +++ b/src/librustuv/addrinfo.rs @@ -133,7 +133,7 @@ fn each_ai_flag(_f: |c_int, ai::Flag|) { } // Traverse the addrinfo linked list, producing a vector of Rust socket addresses -pub fn accum_addrinfo(addr: &Addrinfo) -> ~[ai::Info] { +fn accum_addrinfo(addr: &Addrinfo) -> ~[ai::Info] { unsafe { let mut addr = addr.handle; diff --git a/src/librustuv/homing.rs b/src/librustuv/homing.rs index 16534b7b38bab..5fa090b3d7bc2 100644 --- a/src/librustuv/homing.rs +++ b/src/librustuv/homing.rs @@ -53,6 +53,7 @@ pub struct HomeHandle { } impl HomeHandle { + #[allow(visible_local_types)] pub fn new(id: uint, pool: &mut QueuePool) -> HomeHandle { HomeHandle { queue: pool.queue(), id: id } } diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs index 36305c26682af..b5f1f67f7796c 100644 --- a/src/librustuv/lib.rs +++ b/src/librustuv/lib.rs @@ -65,6 +65,8 @@ pub use self::signal::SignalWatcher; pub use self::timer::TimerWatcher; pub use self::tty::TtyWatcher; +pub use self::homing::HomeHandle; + mod macros; mod queue; diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index 26d67daf7c147..ebbd51524cbf8 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -243,7 +243,7 @@ use vec::OwnedVector; use spsc = sync::spsc_queue; use mpsc = sync::mpsc_queue; -pub use self::select::Select; +pub use self::select::{Select, Handle}; macro_rules! test ( { fn $name:ident() $b:block $($a:attr)*} => ( diff --git a/src/libstd/comm/select.rs b/src/libstd/comm/select.rs index 6a10ac56a4ef4..96c345f368906 100644 --- a/src/libstd/comm/select.rs +++ b/src/libstd/comm/select.rs @@ -89,6 +89,7 @@ pub struct Select { /// This handle is used to keep the port in the set as well as interact with the /// underlying port. pub struct Handle<'port, T> { + /// A unique ID for this Handle. id: uint, priv selector: &'port Select, priv port: &'port mut Port, diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index 3082798336069..3b1c45d752727 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -1268,7 +1268,7 @@ pub trait Acceptor { /// The Some contains another Option representing whether the connection attempt was succesful. /// A successful connection will be wrapped in Some. /// A failed connection is represented as a None and raises a condition. -struct IncomingConnections<'a, A> { +pub struct IncomingConnections<'a, A> { priv inc: &'a mut A, } diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 7aa966802f2f5..b80bbe6888d5d 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -113,10 +113,10 @@ pub mod logging; pub mod crate_map; /// The runtime needs to be able to put a pointer into thread-local storage. -mod local_ptr; +pub mod local_ptr; /// Bindings to pthread/windows thread-local storage. -mod thread_local_storage; +pub mod thread_local_storage; /// Stack unwinding pub mod unwind; diff --git a/src/libstd/rt/unwind.rs b/src/libstd/rt/unwind.rs index 6f3aa4c4fd07b..e47e61ff5acd9 100644 --- a/src/libstd/rt/unwind.rs +++ b/src/libstd/rt/unwind.rs @@ -265,6 +265,7 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class { #[cfg(not(target_arch = "arm"), not(test))] #[doc(hidden)] +#[allow(visible_local_types)] pub mod eabi { use uw = super::libunwind; use libc::c_int; diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 95a02e1631a9a..39ad81a209ada 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -620,7 +620,7 @@ enum NormalizationForm { /// External iterator for a string's normalization's characters. /// Use with the `std::iter` module. #[deriving(Clone)] -struct Normalizations<'a> { +pub struct Normalizations<'a> { priv kind: NormalizationForm, priv iter: Chars<'a>, priv buffer: ~[(char, u8)], diff --git a/src/libsyntax/abi.rs b/src/libsyntax/abi.rs index 9194acfcdec45..9aa21f70451e9 100644 --- a/src/libsyntax/abi.rs +++ b/src/libsyntax/abi.rs @@ -47,7 +47,7 @@ pub enum Architecture { static IntelBits: u32 = (1 << (X86 as uint)) | (1 << (X86_64 as uint)); static ArmBits: u32 = (1 << (Arm as uint)); -struct AbiData { +pub struct AbiData { abi: Abi, // Name of this ABI as we like it called. @@ -58,7 +58,7 @@ struct AbiData { abi_arch: AbiArchitecture } -enum AbiArchitecture { +pub enum AbiArchitecture { RustArch, // Not a real ABI (e.g., intrinsic) AllArch, // An ABI that specifies cross-platform defaults (e.g., "C") Archs(u32) // Multiple architectures (bitset) diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 8698220130350..3cec1553ab425 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -56,7 +56,7 @@ pub type SyntaxExpanderTTFunNoCtxt = fn(ecx: &mut ExtCtxt, span: codemap::Span, token_tree: &[ast::TokenTree]) -> MacResult; -enum SyntaxExpanderTTExpander { +pub enum SyntaxExpanderTTExpander { SyntaxExpanderTTExpanderWithoutContext(SyntaxExpanderTTFunNoCtxt), } @@ -75,7 +75,7 @@ impl SyntaxExpanderTTTrait for SyntaxExpanderTT { } } -enum SyntaxExpanderTTItemExpander { +pub enum SyntaxExpanderTTItemExpander { SyntaxExpanderTTItemExpanderWithContext(SyntaxExpanderTTItemFun), SyntaxExpanderTTItemExpanderWithoutContext(SyntaxExpanderTTItemFunNoCtxt), } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index f547f32e21dbc..5e67caf1a8e58 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -620,8 +620,8 @@ fn expand_non_macro_stmt(s: &Stmt, fld: &mut MacroExpander) // from a given thingy and puts them in a mutable // array (passed in to the traversal) #[deriving(Clone)] -struct NewNameFinderContext { - ident_accumulator: ~[ast::Ident], +pub struct NewNameFinderContext { + priv ident_accumulator: ~[ast::Ident], } impl Visitor<()> for NewNameFinderContext { @@ -710,8 +710,8 @@ pub fn expand_block_elts(b: &Block, fld: &mut MacroExpander) -> P { }) } -struct IdentRenamer<'a> { - renames: &'a mut RenameList, +pub struct IdentRenamer<'a> { + priv renames: &'a mut RenameList, } impl<'a> Folder for IdentRenamer<'a> { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 557e7e04ebfc5..1e8f34f880285 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -87,14 +87,14 @@ use std::vec; #[allow(non_camel_case_types)] #[deriving(Eq)] -enum restriction { +pub enum restriction { UNRESTRICTED, RESTRICT_STMT_EXPR, RESTRICT_NO_BAR_OP, RESTRICT_NO_BAR_OR_DOUBLEBAR_OP, } -type ItemInfo = (Ident, Item_, Option<~[Attribute]>); +pub type ItemInfo = (Ident, Item_, Option<~[Attribute]>); /// How to parse a path. There are four different kinds of paths, all of which /// are parsed somewhat differently. @@ -116,13 +116,13 @@ pub enum PathParsingMode { /// A pair of a path segment and group of type parameter bounds. (See `ast.rs` /// for the definition of a path segment.) -struct PathSegmentAndBoundSet { +pub struct PathSegmentAndBoundSet { segment: ast::PathSegment, bound_set: Option>, } /// A path paired with optional type bounds. -struct PathAndBounds { +pub struct PathAndBounds { path: ast::Path, bounds: Option>, } diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index 902d9e1c28468..c8b1635cffc90 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -139,12 +139,12 @@ pub fn buf_str(toks: ~[Token], szs: ~[int], left: uint, right: uint, return s; } -enum PrintStackBreak { +pub enum PrintStackBreak { Fits, Broken(Breaks), } -struct PrintStackElem { +pub struct PrintStackElem { offset: int, pbreak: PrintStackBreak } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 54e9a8bd62937..8ca823a352681 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -951,7 +951,7 @@ pub fn print_block_with_attrs(s: &mut State, true); } -enum EmbedType { +pub enum EmbedType { BlockBlockFn, BlockNormal, } diff --git a/src/test/compile-fail/lint-visible-local-types.rs b/src/test/compile-fail/lint-visible-local-types.rs new file mode 100644 index 0000000000000..ad71cf617eb98 --- /dev/null +++ b/src/test/compile-fail/lint-visible-local-types.rs @@ -0,0 +1,100 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[deny(visible_local_types)]; +#[allow(dead_code, unused_variable)]; + +pub use Reexport = Reexported; + +struct Private; +struct Reexported; +pub struct Public; + + +trait PrivTrait { + fn ok_1(&self, ok_1: Public, ok_2: Reexported, ok_3: Private) {} + fn ok_2(&self, ok_1: Public, ok_2: Reexported, ok_3: Private); +} + +impl PrivTrait for Public { + fn ok_2(&self, ok_1: Public, ok_2: Reexported, ok_3: Private) {} +} + +pub trait PubTrait { + fn err_1(&self, + ok_1: Public, + ok_2: Reexported, + err: Private) {} //~ ERROR non-exported type used in exported method signature + + fn err_2(&self, err: Private); //~ ERROR non-exported type used in exported method signature +} + +impl PubTrait for Option { + fn err_2(&self, ok: Private) {} +} + +impl Private { + pub fn ok() -> Private { Private } +} +impl Public { + pub fn err() -> Private { //~ ERROR non-exported type used in exported method signature + Private + } +} + +pub struct PublicStruct { + priv ok_1: Private, + + ok_2: Public, + ok_3: Reexported, + err: Private //~ ERROR non-exported type used in exported struct field +} + +struct PrivateStruct { + ok_1: Public, + ok_2: Private +} + + +pub enum PublicEnum { + priv PubOk1(Private), + + PubOk2(Public), + PubOk3(Reexported), + PubErr(Private) //~ ERROR non-exported type used in exported enum variant +} + +enum PrivateEnum { + PrivOk1(Private), + PrivOk2(Public), + + pub PrivOk3(Public), + pub PrivOk4(Reexported), + pub PrivErr(Private) // FIXME #11680 (ERROR non-exported type used in exported enum variant) +} + +pub fn public_fn( + ok_1: Public, + ok_2: &PrivTrait, + ok_3: Reexported, + err_1: Private, //~ ERROR non-exported type used in exported function signature + err_2: || -> Private //~ ERROR non-exported type used in exported function signature + ) -> Option { //~ ERROR non-exported type used in exported function signature + None +} + +fn private_fn( + ok_1: Public, + ok_2: Private, + ok_3: &PrivTrait, + ok_4: || -> Private + ) -> Option { + None +}