diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index 625b89b3bae..fb70cb5b752 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -94,7 +94,7 @@ pub enum Void { }
 pub trait Any: AnyPrivate {}
 
 /// An inner trait to ensure that only this module can call `get_type_id()`.
-trait AnyPrivate {
+pub trait AnyPrivate {
     /// Get the `TypeId` of `self`
     fn get_type_id(&self) -> TypeId;
 }
diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index 6bee0573fac..f84c5eec452 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -2178,7 +2178,6 @@ pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>;
 
 /// Creates a new iterator that produces an infinite sequence of
 /// repeated applications of the given function `f`.
-#[allow(visible_private_types)]
 pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> {
     Unfold::new((f, Some(seed), true), |st| {
         let &(ref mut f, ref mut val, ref mut first) = st;
diff --git a/src/libdebug/repr.rs b/src/libdebug/repr.rs
index 7fe6f2dbf67..e1eb2814951 100644
--- a/src/libdebug/repr.rs
+++ b/src/libdebug/repr.rs
@@ -32,7 +32,7 @@ macro_rules! try( ($me:expr, $e:expr) => (
 
 /// Representations
 
-trait Repr {
+pub trait Repr {
     fn write_repr(&self, writer: &mut io::Writer) -> io::IoResult<()>;
 }
 
diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs
index 00f246ea05e..b5da4dc24bb 100644
--- a/src/libgreen/lib.rs
+++ b/src/libgreen/lib.rs
@@ -218,7 +218,7 @@
 
 // NB this does *not* include globs, please keep it that way.
 #![feature(macro_rules, phase, default_type_params)]
-#![allow(visible_private_types, deprecated)]
+#![allow(deprecated)]
 
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 #[cfg(test)] extern crate rustuv;
@@ -385,7 +385,7 @@ 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 {
+pub struct TaskState {
     cnt: Arc<AtomicUint>,
     done: Sender<()>,
 }
diff --git a/src/libnative/io/timer_unix.rs b/src/libnative/io/timer_unix.rs
index 0a5de325c09..8c6fd83a76b 100644
--- a/src/libnative/io/timer_unix.rs
+++ b/src/libnative/io/timer_unix.rs
@@ -66,7 +66,7 @@ pub struct Timer {
     inner: Option<Box<Inner>>,
 }
 
-struct Inner {
+pub struct Inner {
     cb: Option<Box<rtio::Callback + Send>>,
     interval: u64,
     repeat: bool,
@@ -74,7 +74,6 @@ struct Inner {
     id: uint,
 }
 
-#[allow(visible_private_types)]
 pub enum Req {
     // Add a new timer to the helper thread.
     NewTimer(Box<Inner>),
diff --git a/src/libregex/compile.rs b/src/libregex/compile.rs
index 91c3da00162..14d32ed6eaa 100644
--- a/src/libregex/compile.rs
+++ b/src/libregex/compile.rs
@@ -10,7 +10,6 @@
 
 // Enable this to squash warnings due to exporting pieces of the representation
 // for use with the regex! macro. See lib.rs for explanation.
-#![allow(visible_private_types)]
 
 use std::cmp;
 use parse;
diff --git a/src/libregex/re.rs b/src/libregex/re.rs
index c2578d227ee..32a88cfb76d 100644
--- a/src/libregex/re.rs
+++ b/src/libregex/re.rs
@@ -102,7 +102,6 @@ pub fn is_match(regex: &str, text: &str) -> Result<bool, parse::Error> {
 /// More details about the `regex!` macro can be found in the `regex` crate
 /// documentation.
 #[deriving(Clone)]
-#[allow(visible_private_types)]
 pub enum Regex {
     // The representation of `Regex` is exported to support the `regex!`
     // syntax extension. Do not rely on it.
@@ -516,7 +515,6 @@ impl Regex {
     }
 
     #[doc(hidden)]
-    #[allow(visible_private_types)]
     #[experimental]
     pub fn names_iter<'a>(&'a self) -> NamesIter<'a> {
         match *self {
@@ -534,7 +532,7 @@ impl Regex {
 
 }
 
-enum NamesIter<'a> {
+pub enum NamesIter<'a> {
     NamesIterNative(::std::slice::Items<'a, Option<&'static str>>),
     NamesIterDynamic(::std::slice::Items<'a, Option<String>>)
 }
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 6c3f96bbec6..b4685ce456a 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -1601,9 +1601,6 @@ declare_lint!(pub DEAD_ASSIGNMENT, Warn,
 declare_lint!(pub DEAD_CODE, Warn,
               "detect piece of code that will never be used")
 
-declare_lint!(pub VISIBLE_PRIVATE_TYPES, Warn,
-              "detect use of private types in exported type signatures")
-
 declare_lint!(pub UNREACHABLE_CODE, Warn,
               "detects unreachable code")
 
@@ -1636,7 +1633,6 @@ impl LintPass for HardwiredLints {
             UNUSED_VARIABLE,
             DEAD_ASSIGNMENT,
             DEAD_CODE,
-            VISIBLE_PRIVATE_TYPES,
             UNREACHABLE_CODE,
             WARNINGS,
             UNKNOWN_FEATURES,
diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs
index 6350fa6a506..c3b477da4bc 100644
--- a/src/librustc/middle/mem_categorization.rs
+++ b/src/librustc/middle/mem_categorization.rs
@@ -224,7 +224,7 @@ pub fn deref_kind(tcx: &ty::ctxt, t: ty::t) -> deref_kind {
     }
 }
 
-trait ast_node {
+pub trait ast_node {
     fn id(&self) -> ast::NodeId;
     fn span(&self) -> Span;
 }
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index 36778e7cfc3..bf16f772775 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -16,7 +16,6 @@ use std::mem::replace;
 
 use metadata::csearch;
 use middle::def;
-use lint;
 use middle::resolve;
 use middle::ty;
 use middle::typeck::{MethodCall, MethodMap, MethodOrigin, MethodParam, MethodTypeParam};
@@ -1289,12 +1288,15 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
         };
         // A path can only be private if:
         // it's in this crate...
-        is_local(did) &&
-            // ... it's not exported (obviously) ...
-            !self.exported_items.contains(&did.node) &&
-            // .. and it corresponds to a type in the AST (this returns None for
-            // type parameters)
-            self.tcx.map.find(did.node).is_some()
+        if !is_local(did) {
+            return false
+        }
+        // .. and it corresponds to a private type in the AST (this returns
+        // None for type parameters)
+        match self.tcx.map.find(did.node) {
+            Some(ast_map::NodeItem(ref item)) => item.vis != ast::Public,
+            Some(_) | None => false,
+        }
     }
 
     fn trait_is_public(&self, trait_id: ast::NodeId) -> bool {
@@ -1302,6 +1304,22 @@ impl<'a, 'tcx> VisiblePrivateTypesVisitor<'a, 'tcx> {
         // traits are exported currently (see `EmbargoVisitor.exported_trait`)
         self.public_items.contains(&trait_id)
     }
+
+    fn check_ty_param_bound(&self,
+                            span: Span,
+                            ty_param_bound: &ast::TyParamBound) {
+        match *ty_param_bound {
+            ast::TraitTyParamBound(ref trait_ref) => {
+                if !self.tcx.sess.features.borrow().visible_private_types &&
+                        self.path_is_private_type(trait_ref.ref_id) {
+                    self.tcx.sess.span_err(span,
+                                           "private type in exported type \
+                                            parameter bound");
+                }
+            }
+            _ => {}
+        }
+    }
 }
 
 impl<'a, 'b, 'tcx, 'v> Visitor<'v> for CheckTypeForPrivatenessVisitor<'a, 'b, 'tcx> {
@@ -1338,7 +1356,15 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
             // namespace (the contents have their own privacies).
             ast::ItemForeignMod(_) => {}
 
-            ast::ItemTrait(..) if !self.trait_is_public(item.id) => return,
+            ast::ItemTrait(_, _, ref bounds, _) => {
+                if !self.trait_is_public(item.id) {
+                    return
+                }
+
+                for bound in bounds.iter() {
+                    self.check_ty_param_bound(item.span, bound)
+                }
+            }
 
             // impls need some special handling to try to offer useful
             // error messages without (too many) false positives
@@ -1471,6 +1497,19 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
         visit::walk_item(self, item);
     }
 
+    fn visit_generics(&mut self, generics: &ast::Generics) {
+        for ty_param in generics.ty_params.iter() {
+            for bound in ty_param.bounds.iter() {
+                self.check_ty_param_bound(ty_param.span, bound)
+            }
+        }
+        for predicate in generics.where_clause.predicates.iter() {
+            for bound in predicate.bounds.iter() {
+                self.check_ty_param_bound(predicate.span, bound)
+            }
+        }
+    }
+
     fn visit_foreign_item(&mut self, item: &ast::ForeignItem) {
         if self.exported_items.contains(&item.id) {
             visit::walk_foreign_item(self, item)
@@ -1488,12 +1527,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for VisiblePrivateTypesVisitor<'a, 'tcx> {
     fn visit_ty(&mut self, t: &ast::Ty) {
         match t.node {
             ast::TyPath(ref p, _, path_id) => {
-                if self.path_is_private_type(path_id) {
-                    self.tcx.sess.add_lint(
-                        lint::builtin::VISIBLE_PRIVATE_TYPES,
-                        path_id, p.span,
-                        "private type in exported type \
-                         signature".to_string());
+                if !self.tcx.sess.features.borrow().visible_private_types &&
+                        self.path_is_private_type(path_id) {
+                    self.tcx.sess.span_err(p.span,
+                                           "private type in exported type \
+                                            signature");
                 }
             }
             _ => {}
diff --git a/src/librustc/middle/typeck/infer/error_reporting.rs b/src/librustc/middle/typeck/infer/error_reporting.rs
index 6ea80a59230..646c754b63b 100644
--- a/src/librustc/middle/typeck/infer/error_reporting.rs
+++ b/src/librustc/middle/typeck/infer/error_reporting.rs
@@ -1645,7 +1645,7 @@ impl<'a, 'tcx> ErrorReportingHelpers for InferCtxt<'a, 'tcx> {
     }
 }
 
-trait Resolvable {
+pub trait Resolvable {
     fn resolve(&self, infcx: &InferCtxt) -> Self;
     fn contains_error(&self) -> bool;
 }
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index 22e7ec6124f..c25ef2ca63a 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -153,7 +153,7 @@ pub enum AttributeSet {
     FunctionIndex = !0
 }
 
-trait AttrHelper {
+pub trait AttrHelper {
     fn apply_llfn(&self, idx: c_uint, llfn: ValueRef);
     fn apply_callsite(&self, idx: c_uint, callsite: ValueRef);
 }
diff --git a/src/librustrt/local.rs b/src/librustrt/local.rs
index e2a5eef0d99..8531f569a6b 100644
--- a/src/librustrt/local.rs
+++ b/src/librustrt/local.rs
@@ -26,7 +26,6 @@ pub trait Local<Borrowed> {
     unsafe fn try_unsafe_borrow() -> Option<*mut Self>;
 }
 
-#[allow(visible_private_types)]
 impl Local<local_ptr::Borrowed<Task>> for Task {
     #[inline]
     fn put(value: Box<Task>) { unsafe { local_ptr::put(value) } }
diff --git a/src/librustrt/local_ptr.rs b/src/librustrt/local_ptr.rs
index 92a67da20b6..912e4ef4d40 100644
--- a/src/librustrt/local_ptr.rs
+++ b/src/librustrt/local_ptr.rs
@@ -374,7 +374,6 @@ pub mod native {
 
     #[inline]
     #[cfg(not(test))]
-    #[allow(visible_private_types)]
     pub fn maybe_tls_key() -> Option<tls::Key> {
         unsafe {
             // NB: This is a little racy because, while the key is
diff --git a/src/librustrt/unwind.rs b/src/librustrt/unwind.rs
index fbbc1a08fd9..acef05e0867 100644
--- a/src/librustrt/unwind.rs
+++ b/src/librustrt/unwind.rs
@@ -237,7 +237,6 @@ fn rust_exception_class() -> uw::_Unwind_Exception_Class {
 
 #[cfg(not(target_arch = "arm"), not(windows, target_arch = "x86_64"), not(test))]
 #[doc(hidden)]
-#[allow(visible_private_types)]
 pub mod eabi {
     use libunwind as uw;
     use libc::c_int;
@@ -291,7 +290,6 @@ pub mod eabi {
 
 #[cfg(target_os = "ios", target_arch = "arm", not(test))]
 #[doc(hidden)]
-#[allow(visible_private_types)]
 pub mod eabi {
     use libunwind as uw;
     use libc::c_int;
@@ -347,7 +345,6 @@ pub mod eabi {
 // but otherwise works the same.
 #[cfg(target_arch = "arm", not(target_os = "ios"), not(test))]
 #[doc(hidden)]
-#[allow(visible_private_types)]
 pub mod eabi {
     use libunwind as uw;
     use libc::c_int;
@@ -397,21 +394,20 @@ pub mod eabi {
 
 #[cfg(windows, target_arch = "x86_64", not(test))]
 #[doc(hidden)]
-#[allow(visible_private_types)]
 #[allow(non_camel_case_types, non_snake_case)]
 pub mod eabi {
     use libunwind as uw;
     use libc::{c_void, c_int};
 
     #[repr(C)]
-    struct EXCEPTION_RECORD;
+    pub struct EXCEPTION_RECORD;
     #[repr(C)]
-    struct CONTEXT;
+    pub struct CONTEXT;
     #[repr(C)]
-    struct DISPATCHER_CONTEXT;
+    pub struct DISPATCHER_CONTEXT;
 
     #[repr(C)]
-    enum EXCEPTION_DISPOSITION {
+    pub enum EXCEPTION_DISPOSITION {
         ExceptionContinueExecution,
         ExceptionContinueSearch,
         ExceptionNestedException,
diff --git a/src/librustuv/addrinfo.rs b/src/librustuv/addrinfo.rs
index 995f73af258..609ce016d38 100644
--- a/src/librustuv/addrinfo.rs
+++ b/src/librustuv/addrinfo.rs
@@ -19,7 +19,7 @@ use net;
 use super::{Loop, UvError, Request, wait_until_woken_after, wakeup};
 use uvll;
 
-struct Addrinfo {
+pub struct Addrinfo {
     handle: *const libc::addrinfo,
 }
 
diff --git a/src/librustuv/lib.rs b/src/librustuv/lib.rs
index 7cbfac1cf45..44cfafe3074 100644
--- a/src/librustuv/lib.rs
+++ b/src/librustuv/lib.rs
@@ -46,7 +46,6 @@ via `close` and `delete` methods.
 
 #![feature(macro_rules, unsafe_destructor)]
 #![deny(unused_result, unused_must_use)]
-#![allow(visible_private_types)]
 
 #![reexport_test_harness_main = "test_main"]
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 5203ed0a073..cd0fa184a09 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -69,6 +69,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
     ("advanced_slice_patterns", Active),
     ("tuple_indexing", Active),
     ("associated_types", Active),
+    ("visible_private_types", Active),
 
     // if you change this list without updating src/doc/rust.md, cmr will be sad
 
@@ -100,6 +101,7 @@ pub struct Features {
     pub overloaded_calls: bool,
     pub rustc_diagnostic_macros: bool,
     pub import_shadowing: bool,
+    pub visible_private_types: bool,
 }
 
 impl Features {
@@ -109,6 +111,7 @@ impl Features {
             overloaded_calls: false,
             rustc_diagnostic_macros: false,
             import_shadowing: false,
+            visible_private_types: false,
         }
     }
 }
@@ -479,6 +482,7 @@ pub fn check_crate(span_handler: &SpanHandler, krate: &ast::Crate) -> (Features,
         overloaded_calls: cx.has_feature("overloaded_calls"),
         rustc_diagnostic_macros: cx.has_feature("rustc_diagnostic_macros"),
         import_shadowing: cx.has_feature("import_shadowing"),
+        visible_private_types: cx.has_feature("visible_private_types"),
     },
     unknown_features)
 }
diff --git a/src/test/auxiliary/iss.rs b/src/test/auxiliary/iss.rs
index 095cc3ec1a0..75728c075d1 100644
--- a/src/test/auxiliary/iss.rs
+++ b/src/test/auxiliary/iss.rs
@@ -12,7 +12,7 @@
 
 // part of issue-6919.rs
 
-struct C<'a> {
+pub struct C<'a> {
     pub k: ||: 'a,
 }
 
diff --git a/src/test/auxiliary/noexporttypelib.rs b/src/test/auxiliary/noexporttypelib.rs
index 4e9e3688ecd..94b079b1dcf 100644
--- a/src/test/auxiliary/noexporttypelib.rs
+++ b/src/test/auxiliary/noexporttypelib.rs
@@ -8,5 +8,5 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type oint = Option<int>;
+pub type oint = Option<int>;
 pub fn foo() -> oint { Some(3) }
diff --git a/src/test/auxiliary/priv-impl-prim-ty.rs b/src/test/auxiliary/priv-impl-prim-ty.rs
index 16d3ca8fa64..8c07dd5b785 100644
--- a/src/test/auxiliary/priv-impl-prim-ty.rs
+++ b/src/test/auxiliary/priv-impl-prim-ty.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait A {
+pub trait A {
     fn frob(&self);
 }
 
diff --git a/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs b/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs
index a7429ca534b..1e9fd035f44 100644
--- a/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs
+++ b/src/test/auxiliary/regions-bounded-method-type-parameters-cross-crate-lib.rs
@@ -16,7 +16,7 @@ pub enum MaybeOwned<'a> {
     Borrowed(&'a int)
 }
 
-struct Inv<'a> { // invariant w/r/t 'a
+pub struct Inv<'a> { // invariant w/r/t 'a
     x: &'a mut &'a int
 }
 
diff --git a/src/test/codegen/static-method-call-multi.rs b/src/test/codegen/static-method-call-multi.rs
index efac93692f6..996d2203824 100644
--- a/src/test/codegen/static-method-call-multi.rs
+++ b/src/test/codegen/static-method-call-multi.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Struct {
+pub struct Struct {
     field: int
 }
 
diff --git a/src/test/codegen/static-method-call.rs b/src/test/codegen/static-method-call.rs
index 79fb9d8aa29..9c5894fb97a 100644
--- a/src/test/codegen/static-method-call.rs
+++ b/src/test/codegen/static-method-call.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Struct {
+pub struct Struct {
     field: int
 }
 
diff --git a/src/test/codegen/virtual-method-call-struct-return.rs b/src/test/codegen/virtual-method-call-struct-return.rs
index 20bda755f37..ff1a611c4ef 100644
--- a/src/test/codegen/virtual-method-call-struct-return.rs
+++ b/src/test/codegen/virtual-method-call-struct-return.rs
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct Stuff {
+pub struct Stuff {
   a: int,
   b: f64
 }
 
-trait Trait {
+pub trait Trait {
     fn method(&self) -> Stuff;
 }
 
diff --git a/src/test/codegen/virtual-method-call.rs b/src/test/codegen/virtual-method-call.rs
index 513a299cc63..036c0957e99 100644
--- a/src/test/codegen/virtual-method-call.rs
+++ b/src/test/codegen/virtual-method-call.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait Trait {
+pub trait Trait {
     fn method(&self) -> int;
 }
 
diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs
index 8417f7810ea..a2d2c02dc43 100644
--- a/src/test/compile-fail/lint-dead-code-1.rs
+++ b/src/test/compile-fail/lint-dead-code-1.rs
@@ -11,7 +11,6 @@
 #![no_std]
 #![allow(unused_variable)]
 #![allow(non_camel_case_types)]
-#![allow(visible_private_types)]
 #![deny(dead_code)]
 #![feature(lang_items)]
 
@@ -54,7 +53,7 @@ impl SemiUsedStruct {
     fn la_la_la() {}
 }
 struct StructUsedAsField;
-struct StructUsedInEnum;
+pub struct StructUsedInEnum;
 struct StructUsedInGeneric;
 pub struct PubStruct2 {
     #[allow(dead_code)]
diff --git a/src/test/compile-fail/visible-private-types-generics.rs b/src/test/compile-fail/visible-private-types-generics.rs
new file mode 100644
index 00000000000..740848e93cb
--- /dev/null
+++ b/src/test/compile-fail/visible-private-types-generics.rs
@@ -0,0 +1,26 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo {}
+
+pub fn f<T:Foo>() {}    //~ ERROR private type in exported type
+
+pub fn g<T>() where T: Foo {}   //~ ERROR private type in exported type
+
+pub struct H<T:Foo> {   //~ ERROR private type in exported type
+    x: T,
+}
+
+pub struct I<T> where T: Foo {  //~ ERROR private type in exported type
+    x: T,
+}
+
+fn main() {}
+
diff --git a/src/test/compile-fail/visible-private-types-supertrait.rs b/src/test/compile-fail/visible-private-types-supertrait.rs
new file mode 100644
index 00000000000..c4457aaf1e1
--- /dev/null
+++ b/src/test/compile-fail/visible-private-types-supertrait.rs
@@ -0,0 +1,16 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+trait Foo {}
+
+pub trait Bar : Foo {}  //~ ERROR private type in exported type
+
+fn main() {}
+
diff --git a/src/test/run-pass/deriving-enum-single-variant.rs b/src/test/run-pass/deriving-enum-single-variant.rs
index fc03763a3b7..a9bdcf2734b 100644
--- a/src/test/run-pass/deriving-enum-single-variant.rs
+++ b/src/test/run-pass/deriving-enum-single-variant.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-type task_id = int;
+pub type task_id = int;
 
 #[deriving(PartialEq)]
 pub enum Task {
diff --git a/src/test/run-pass/extern-pass-TwoU16s.rs b/src/test/run-pass/extern-pass-TwoU16s.rs
index 8a9231b640e..6161d31c4a9 100644
--- a/src/test/run-pass/extern-pass-TwoU16s.rs
+++ b/src/test/run-pass/extern-pass-TwoU16s.rs
@@ -12,7 +12,7 @@
 // by value.
 
 #[deriving(PartialEq, Show)]
-struct TwoU16s {
+pub struct TwoU16s {
     one: u16, two: u16
 }
 
diff --git a/src/test/run-pass/extern-pass-TwoU32s.rs b/src/test/run-pass/extern-pass-TwoU32s.rs
index 480eef1c6e9..3e6b6502074 100644
--- a/src/test/run-pass/extern-pass-TwoU32s.rs
+++ b/src/test/run-pass/extern-pass-TwoU32s.rs
@@ -12,7 +12,7 @@
 // by value.
 
 #[deriving(PartialEq, Show)]
-struct TwoU32s {
+pub struct TwoU32s {
     one: u32, two: u32
 }
 
diff --git a/src/test/run-pass/extern-pass-TwoU64s.rs b/src/test/run-pass/extern-pass-TwoU64s.rs
index ca0df4728c6..5ad1e89425b 100644
--- a/src/test/run-pass/extern-pass-TwoU64s.rs
+++ b/src/test/run-pass/extern-pass-TwoU64s.rs
@@ -12,7 +12,7 @@
 // by value.
 
 #[deriving(PartialEq, Show)]
-struct TwoU64s {
+pub struct TwoU64s {
     one: u64, two: u64
 }
 
diff --git a/src/test/run-pass/extern-pass-TwoU8s.rs b/src/test/run-pass/extern-pass-TwoU8s.rs
index 7aeb0a0ec84..14ba7c80059 100644
--- a/src/test/run-pass/extern-pass-TwoU8s.rs
+++ b/src/test/run-pass/extern-pass-TwoU8s.rs
@@ -12,7 +12,7 @@
 // by value.
 
 #[deriving(PartialEq, Show)]
-struct TwoU8s {
+pub struct TwoU8s {
     one: u8, two: u8
 }
 
diff --git a/src/test/run-pass/extern-return-TwoU16s.rs b/src/test/run-pass/extern-return-TwoU16s.rs
index 95352e67020..ca9767307f4 100644
--- a/src/test/run-pass/extern-return-TwoU16s.rs
+++ b/src/test/run-pass/extern-return-TwoU16s.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct TwoU16s {
+pub struct TwoU16s {
     one: u16, two: u16
 }
 
diff --git a/src/test/run-pass/extern-return-TwoU32s.rs b/src/test/run-pass/extern-return-TwoU32s.rs
index 81bd0e9559d..8d650459daa 100644
--- a/src/test/run-pass/extern-return-TwoU32s.rs
+++ b/src/test/run-pass/extern-return-TwoU32s.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct TwoU32s {
+pub struct TwoU32s {
     one: u32, two: u32
 }
 
diff --git a/src/test/run-pass/extern-return-TwoU64s.rs b/src/test/run-pass/extern-return-TwoU64s.rs
index 7c37e0f4e68..924aaf811f4 100644
--- a/src/test/run-pass/extern-return-TwoU64s.rs
+++ b/src/test/run-pass/extern-return-TwoU64s.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct TwoU64s {
+pub struct TwoU64s {
     one: u64, two: u64
 }
 
diff --git a/src/test/run-pass/extern-return-TwoU8s.rs b/src/test/run-pass/extern-return-TwoU8s.rs
index d20f5475c4e..1dbce403cc8 100644
--- a/src/test/run-pass/extern-return-TwoU8s.rs
+++ b/src/test/run-pass/extern-return-TwoU8s.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct TwoU8s {
+pub struct TwoU8s {
     one: u8, two: u8
 }
 
diff --git a/src/test/run-pass/issue-10902.rs b/src/test/run-pass/issue-10902.rs
index f8fd96166ea..84d71e1ef5d 100644
--- a/src/test/run-pass/issue-10902.rs
+++ b/src/test/run-pass/issue-10902.rs
@@ -9,16 +9,16 @@
 // except according to those terms.
 
 pub mod two_tuple {
-    trait T {}
-    struct P<'a>(&'a T + 'a, &'a T + 'a);
+    pub trait T {}
+    pub struct P<'a>(&'a T + 'a, &'a T + 'a);
     pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> {
         P(car, cdr)
     }
 }
 
 pub mod two_fields {
-    trait T {}
-    struct P<'a> { car: &'a T + 'a, cdr: &'a T + 'a }
+    pub trait T {}
+    pub struct P<'a> { car: &'a T + 'a, cdr: &'a T + 'a }
     pub fn f<'a>(car: &'a T, cdr: &'a T) -> P<'a> {
         P{ car: car, cdr: cdr }
     }
diff --git a/src/test/run-pass/issue-3656.rs b/src/test/run-pass/issue-3656.rs
index 8fd603781ba..53157ce7546 100644
--- a/src/test/run-pass/issue-3656.rs
+++ b/src/test/run-pass/issue-3656.rs
@@ -15,7 +15,7 @@
 extern crate libc;
 use libc::{c_uint, uint32_t, c_void};
 
-struct KEYGEN {
+pub struct KEYGEN {
     hash_algorithm: [c_uint, ..2],
     count: uint32_t,
     salt: *const c_void,
diff --git a/src/test/run-pass/issue-3753.rs b/src/test/run-pass/issue-3753.rs
index fe2d729bc9e..951832a14aa 100644
--- a/src/test/run-pass/issue-3753.rs
+++ b/src/test/run-pass/issue-3753.rs
@@ -14,7 +14,7 @@
 
 use std::f64;
 
-struct Point {
+pub struct Point {
     x: f64,
     y: f64
 }
diff --git a/src/test/run-pass/issue-5708.rs b/src/test/run-pass/issue-5708.rs
index 6168753b6d7..9c728005b6f 100644
--- a/src/test/run-pass/issue-5708.rs
+++ b/src/test/run-pass/issue-5708.rs
@@ -48,7 +48,7 @@ pub fn main() {
 
 
 // minimal
-trait MyTrait<T> { }
+pub trait MyTrait<T> { }
 
 pub struct MyContainer<'a, T> {
     foos: Vec<&'a MyTrait<T>+'a> ,
diff --git a/src/test/run-pass/regions-no-variance-from-fn-generics.rs b/src/test/run-pass/regions-no-variance-from-fn-generics.rs
index 3814de79bb6..a35ab1bfc0c 100644
--- a/src/test/run-pass/regions-no-variance-from-fn-generics.rs
+++ b/src/test/run-pass/regions-no-variance-from-fn-generics.rs
@@ -12,7 +12,7 @@
 // should not upset the variance inference for actual occurrences of
 // that lifetime in type expressions.
 
-trait HasLife<'a> { }
+pub trait HasLife<'a> { }
 
 trait UseLife01 {
     fn refs<'a, H: HasLife<'a>>(&'a self) -> H;
@@ -23,7 +23,7 @@ trait UseLife02 {
 }
 
 
-trait HasType<T> { }
+pub trait HasType<T> { }
 
 trait UseLife03<T> {
     fn refs<'a, H: HasType<&'a T>>(&'a self) -> H;
diff --git a/src/test/run-pass/struct-partial-move-1.rs b/src/test/run-pass/struct-partial-move-1.rs
index 7e02d102081..d64408ec42f 100644
--- a/src/test/run-pass/struct-partial-move-1.rs
+++ b/src/test/run-pass/struct-partial-move-1.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 #[deriving(PartialEq, Show)]
-struct Partial<T> { x: T, y: T }
+pub struct Partial<T> { x: T, y: T }
 
 #[deriving(PartialEq, Show)]
 struct S { val: int }
diff --git a/src/test/run-pass/struct-partial-move-2.rs b/src/test/run-pass/struct-partial-move-2.rs
index fe5e1eaaa1a..0e77079ed05 100644
--- a/src/test/run-pass/struct-partial-move-2.rs
+++ b/src/test/run-pass/struct-partial-move-2.rs
@@ -9,14 +9,14 @@
 // except according to those terms.
 
 #[deriving(PartialEq, Show)]
-struct Partial<T> { x: T, y: T }
+pub struct Partial<T> { x: T, y: T }
 
 #[deriving(PartialEq, Show)]
 struct S { val: int }
 impl S { fn new(v: int) -> S { S { val: v } } }
 impl Drop for S { fn drop(&mut self) { } }
 
-type Two<T> = (Partial<T>, Partial<T>);
+pub type Two<T> = (Partial<T>, Partial<T>);
 
 pub fn f<T>((b1, b2): (T, T), (b3, b4): (T, T), f: |T| -> T) -> Two<T> {
     let p = Partial { x: b1, y: b2 };
diff --git a/src/test/run-pass/trait-inheritance-num0.rs b/src/test/run-pass/trait-inheritance-num0.rs
index 58709ab4c85..16e702bb79a 100644
--- a/src/test/run-pass/trait-inheritance-num0.rs
+++ b/src/test/run-pass/trait-inheritance-num0.rs
@@ -13,7 +13,7 @@
 
 use std::num::NumCast;
 
-trait Num {
+pub trait Num {
     fn from_int(i: int) -> Self;
     fn gt(&self, other: &Self) -> bool;
 }
diff --git a/src/test/run-pass/trait-inheritance-static.rs b/src/test/run-pass/trait-inheritance-static.rs
index 08543b236f3..611c3e006ec 100644
--- a/src/test/run-pass/trait-inheritance-static.rs
+++ b/src/test/run-pass/trait-inheritance-static.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait MyNum {
+pub trait MyNum {
     fn from_int(int) -> Self;
 }
 
diff --git a/src/test/run-pass/trait-inheritance-static2.rs b/src/test/run-pass/trait-inheritance-static2.rs
index 95131176ce7..3b454aad03e 100644
--- a/src/test/run-pass/trait-inheritance-static2.rs
+++ b/src/test/run-pass/trait-inheritance-static2.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-trait MyEq { }
+pub trait MyEq { }
 
-trait MyNum {
+pub trait MyNum {
     fn from_int(int) -> Self;
 }
 
diff --git a/src/test/run-pass/visible-private-types-feature-gate.rs b/src/test/run-pass/visible-private-types-feature-gate.rs
new file mode 100644
index 00000000000..9518671b479
--- /dev/null
+++ b/src/test/run-pass/visible-private-types-feature-gate.rs
@@ -0,0 +1,22 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(visible_private_types)]
+
+trait Foo {}
+
+pub trait Bar : Foo {}
+
+struct Baz;
+
+pub fn f(_: Baz) {}
+
+fn main() {}
+