Skip to content

Commit cde3ed0

Browse files
committed
librustc: Require that types mentioned anywhere in public signatures be
public, including in trait bounds and typedefs. There are three main patterns that this breaks. First is code that uses private trait bounds in public APIs: pub mod a { trait Trait { ... } pub fn f<T:Trait>() { ... } } Change that code to export the trait. For example: pub mod a { pub trait Trait { ... } // note `pub` pub fn f<T:Trait>() { ... } } Second, this change breaks code that was relying on `#[allow(visible_private_types)]`. That lint is now a hard error, and cannot be overridden. For example: mod helper { pub struct Foo { ... } } pub mod public { use helper::Foo; pub fn f() -> Foo; } Because there is no way for code that uses `public::f` to name `Foo`, this is no longer allowed. Change affected code to look like this: pub mod helper { // note `pub` pub struct Foo { ... } } pub mod public { use helper::Foo; pub fn f() -> Foo; } Third, this change breaks code that was relying on being able to reference private typedefs in public APIs. For example: pub mod b { type Foo = int; pub fn f(_: Foo) { ... } } Change this code to: pub mod b { pub type Foo = int; // note `pub` pub fn f(_: Foo) { ... } } For now, the old behavior can be obtained with `#[feature(visible_private_types)]`. However, the preciase semantics of this feature gate may be unstable. This implements RFC rust-lang#48. Closes rust-lang#16463. [breaking-change]
1 parent 02f9fd8 commit cde3ed0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+175
-112
lines changed

src/libarena/lib.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,12 @@
2828
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
2929
html_root_url = "http://doc.rust-lang.org/master/")]
3030

31-
#![feature(unsafe_destructor)]
31+
#![feature(unsafe_destructor, visible_private_types)]
3232
#![allow(missing_doc)]
3333

34+
// NOTE(stage0, pcwalton): Remove after snapshot.
35+
#![allow(unknown_features)]
36+
3437
use std::cell::{Cell, RefCell};
3538
use std::cmp;
3639
use std::intrinsics::{TyDesc, get_tydesc};
@@ -359,6 +362,7 @@ pub struct TypedArena<T> {
359362
/// A pointer to the first arena segment.
360363
first: RefCell<TypedArenaChunkRef<T>>,
361364
}
365+
362366
type TypedArenaChunkRef<T> = Option<Box<TypedArenaChunk<T>>>;
363367

364368
struct TypedArenaChunk<T> {

src/libcore/iter.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2182,7 +2182,6 @@ pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>;
21822182

21832183
/// Creates a new iterator that produces an infinite sequence of
21842184
/// repeated applications of the given function `f`.
2185-
#[allow(visible_private_types)]
21862185
pub fn iterate<'a, T: Clone>(f: |T|: 'a -> T, seed: T) -> Iterate<'a, T> {
21872186
Unfold::new((f, Some(seed), true), |st| {
21882187
let &(ref mut f, ref mut val, ref mut first) = st;

src/libcore/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,12 @@
5858

5959
#![no_std]
6060
#![feature(globs, intrinsics, lang_items, macro_rules, managed_boxes, phase)]
61-
#![feature(simd, unsafe_destructor)]
61+
#![feature(simd, unsafe_destructor, visible_private_types)]
6262
#![deny(missing_doc)]
6363

64+
// NOTE(stage0, pcwalton): Remove after snapshot.
65+
#![allow(unknown_features)]
66+
6467
mod macros;
6568

6669
#[path = "num/float_macros.rs"] mod float_macros;

src/libdebug/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@
2525
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
2626
html_root_url = "http://doc.rust-lang.org/master/")]
2727
#![experimental]
28-
#![feature(managed_boxes, macro_rules)]
28+
#![feature(managed_boxes, macro_rules, visible_private_types)]
2929
#![allow(experimental)]
3030

31+
// NOTE(stage0, pcwalton): Remove after snapshot.
32+
#![allow(unknown_features)]
33+
3134
pub mod fmt;
3235
pub mod reflect;
3336
pub mod repr;

src/libgreen/lib.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,11 @@
217217
html_playground_url = "http://play.rust-lang.org/")]
218218

219219
// NB this does *not* include globs, please keep it that way.
220-
#![feature(macro_rules, phase, default_type_params)]
221-
#![allow(visible_private_types, deprecated)]
220+
#![feature(macro_rules, phase, default_type_params, visible_private_types)]
221+
#![allow(deprecated)]
222+
223+
// NOTE(stage0, pcwalton): Remove after snapshot.
224+
#![allow(unknown_features)]
222225

223226
#[cfg(test)] #[phase(plugin, link)] extern crate log;
224227
#[cfg(test)] extern crate rustuv;

src/libnative/io/timer_unix.rs

-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ struct Inner {
7474
id: uint,
7575
}
7676

77-
#[allow(visible_private_types)]
7877
pub enum Req {
7978
// Add a new timer to the helper thread.
8079
NewTimer(Box<Inner>),

src/libnative/lib.rs

+4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@
6363
// consider whether they're needed before adding that feature here (the
6464
// answer is that you don't need them)
6565
#![feature(macro_rules, unsafe_destructor, default_type_params)]
66+
#![feature(visible_private_types)]
67+
68+
// NOTE(stage0, pcwalton): Remove after snapshot.
69+
#![allow(unknown_features)]
6670

6771
extern crate alloc;
6872
extern crate libc;

src/libregex/compile.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
// Enable this to squash warnings due to exporting pieces of the representation
12-
// for use with the regex! macro. See lib.rs for explanation.
13-
#![allow(visible_private_types)]
11+
#![allow(missing_doc)]
1412

1513
use std::cmp;
1614
use parse;

src/libregex/lib.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,12 @@
368368
html_root_url = "http://doc.rust-lang.org/master/",
369369
html_playground_url = "http://play.rust-lang.org/")]
370370

371-
#![feature(macro_rules, phase)]
371+
#![feature(macro_rules, phase, visible_private_types)]
372372
#![deny(missing_doc)]
373373

374+
// NOTE(stage0, pcwalton): Remove after snapshot.
375+
#![allow(unknown_features)]
376+
374377
#[cfg(test)]
375378
extern crate stdtest = "test";
376379
#[cfg(test)]

src/libregex/re.rs

-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ pub fn is_match(regex: &str, text: &str) -> Result<bool, parse::Error> {
102102
/// More details about the `regex!` macro can be found in the `regex` crate
103103
/// documentation.
104104
#[deriving(Clone)]
105-
#[allow(visible_private_types)]
106105
pub enum Regex {
107106
// The representation of `Regex` is exported to support the `regex!`
108107
// syntax extension. Do not rely on it.
@@ -516,7 +515,6 @@ impl Regex {
516515
}
517516

518517
#[doc(hidden)]
519-
#[allow(visible_private_types)]
520518
#[experimental]
521519
pub fn names_iter<'a>(&'a self) -> NamesIter<'a> {
522520
match *self {

src/librustc/front/feature_gate.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ static KNOWN_FEATURES: &'static [(&'static str, Status)] = &[
6868

6969
("rustc_diagnostic_macros", Active),
7070
("unboxed_closures", Active),
71+
("visible_private_types", Active),
7172

7273
// if you change this list without updating src/doc/rust.md, cmr will be sad
7374

@@ -98,7 +99,8 @@ pub struct Features {
9899
pub default_type_params: Cell<bool>,
99100
pub issue_5723_bootstrap: Cell<bool>,
100101
pub overloaded_calls: Cell<bool>,
101-
pub rustc_diagnostic_macros: Cell<bool>
102+
pub rustc_diagnostic_macros: Cell<bool>,
103+
pub visible_private_types: Cell<bool>,
102104
}
103105

104106
impl Features {
@@ -107,7 +109,8 @@ impl Features {
107109
default_type_params: Cell::new(false),
108110
issue_5723_bootstrap: Cell::new(false),
109111
overloaded_calls: Cell::new(false),
110-
rustc_diagnostic_macros: Cell::new(false)
112+
rustc_diagnostic_macros: Cell::new(false),
113+
visible_private_types: Cell::new(false),
111114
}
112115
}
113116
}
@@ -439,4 +442,5 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
439442
sess.features.issue_5723_bootstrap.set(cx.has_feature("issue_5723_bootstrap"));
440443
sess.features.overloaded_calls.set(cx.has_feature("overloaded_calls"));
441444
sess.features.rustc_diagnostic_macros.set(cx.has_feature("rustc_diagnostic_macros"));
445+
sess.features.visible_private_types.set(cx.has_feature("visible_private_types"));
442446
}

src/librustc/lint/builtin.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1539,9 +1539,6 @@ declare_lint!(pub DEAD_ASSIGNMENT, Warn,
15391539
declare_lint!(pub DEAD_CODE, Warn,
15401540
"detect piece of code that will never be used")
15411541

1542-
declare_lint!(pub VISIBLE_PRIVATE_TYPES, Warn,
1543-
"detect use of private types in exported type signatures")
1544-
15451542
declare_lint!(pub UNREACHABLE_CODE, Warn,
15461543
"detects unreachable code")
15471544

@@ -1570,7 +1567,6 @@ impl LintPass for HardwiredLints {
15701567
UNUSED_VARIABLE,
15711568
DEAD_ASSIGNMENT,
15721569
DEAD_CODE,
1573-
VISIBLE_PRIVATE_TYPES,
15741570
UNREACHABLE_CODE,
15751571
WARNINGS,
15761572
UNKNOWN_FEATURES,

src/librustc/middle/mem_categorization.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ pub fn deref_kind(tcx: &ty::ctxt, t: ty::t) -> deref_kind {
224224
}
225225
}
226226

227-
trait ast_node {
227+
pub trait ast_node {
228228
fn id(&self) -> ast::NodeId;
229229
fn span(&self) -> Span;
230230
}

src/librustc/middle/privacy.rs

+26-43
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ use std::mem::replace;
1717

1818
use metadata::csearch;
1919
use middle::def;
20-
use lint;
2120
use middle::resolve;
2221
use middle::ty;
2322
use middle::typeck::{MethodCall, MethodMap, MethodOrigin, MethodParam};
@@ -163,23 +162,6 @@ struct EmbargoVisitor<'a> {
163162
prev_public: bool,
164163
}
165164

166-
impl<'a> EmbargoVisitor<'a> {
167-
// There are checks inside of privacy which depend on knowing whether a
168-
// trait should be exported or not. The two current consumers of this are:
169-
//
170-
// 1. Should default methods of a trait be exported?
171-
// 2. Should the methods of an implementation of a trait be exported?
172-
//
173-
// The answer to both of these questions partly rely on whether the trait
174-
// itself is exported or not. If the trait is somehow exported, then the
175-
// answers to both questions must be yes. Right now this question involves
176-
// more analysis than is currently done in rustc, so we conservatively
177-
// answer "yes" so that all traits need to be exported.
178-
fn exported_trait(&self, _id: ast::NodeId) -> bool {
179-
true
180-
}
181-
}
182-
183165
impl<'a> Visitor<()> for EmbargoVisitor<'a> {
184166
fn visit_item(&mut self, item: &ast::Item, _: ()) {
185167
let orig_all_pub = self.prev_public;
@@ -194,12 +176,6 @@ impl<'a> Visitor<()> for EmbargoVisitor<'a> {
194176
// cannot have visibility qualifiers on them anyway
195177
ast::ItemImpl(..) | ast::ItemForeignMod(..) => {}
196178

197-
// Traits are a little special in that even if they themselves are
198-
// not public they may still be exported.
199-
ast::ItemTrait(..) => {
200-
self.prev_exported = self.exported_trait(item.id);
201-
}
202-
203179
// Private by default, hence we only retain the "public chain" if
204180
// `pub` is explicitly listed.
205181
_ => {
@@ -1218,7 +1194,6 @@ impl<'a> SanePrivacyVisitor<'a> {
12181194
struct VisiblePrivateTypesVisitor<'a> {
12191195
tcx: &'a ty::ctxt,
12201196
exported_items: &'a ExportedItems,
1221-
public_items: &'a PublicItems,
12221197
}
12231198

12241199
struct CheckTypeForPrivatenessVisitor<'a, 'b> {
@@ -1250,9 +1225,14 @@ impl<'a> VisiblePrivateTypesVisitor<'a> {
12501225
}
12511226

12521227
fn trait_is_public(&self, trait_id: ast::NodeId) -> bool {
1253-
// FIXME: this would preferably be using `exported_items`, but all
1254-
// traits are exported currently (see `EmbargoVisitor.exported_trait`)
1255-
self.public_items.contains(&trait_id)
1228+
self.exported_items.contains(&trait_id)
1229+
}
1230+
1231+
fn check_path(&self, path: &ast::Path, path_id: ast::NodeId) {
1232+
if self.path_is_private_type(path_id) {
1233+
self.tcx.sess.span_err(path.span,
1234+
"private type in exported type signature");
1235+
}
12561236
}
12571237
}
12581238

@@ -1407,10 +1387,6 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
14071387
return
14081388
}
14091389

1410-
// `type ... = ...;` can contain private types, because
1411-
// we're introducing a new name.
1412-
ast::ItemTy(..) => return,
1413-
14141390
// not at all public, so we don't care
14151391
_ if !self.exported_items.contains(&item.id) => return,
14161392

@@ -1439,17 +1415,24 @@ impl<'a> Visitor<()> for VisiblePrivateTypesVisitor<'a> {
14391415
}
14401416
}
14411417

1442-
fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
1443-
match t.node {
1444-
ast::TyPath(ref p, _, path_id) => {
1445-
if self.path_is_private_type(path_id) {
1446-
self.tcx.sess.add_lint(
1447-
lint::builtin::VISIBLE_PRIVATE_TYPES,
1448-
path_id, p.span,
1449-
"private type in exported type \
1450-
signature".to_string());
1418+
fn visit_generics(&mut self, g: &ast::Generics, _: ()) {
1419+
for type_parameter in g.ty_params.iter() {
1420+
for bound in type_parameter.bounds.iter() {
1421+
match *bound {
1422+
ast::TraitTyParamBound(ref trait_ref) => {
1423+
self.check_path(&trait_ref.path, trait_ref.ref_id)
1424+
}
1425+
ast::StaticRegionTyParamBound |
1426+
ast::UnboxedFnTyParamBound(_) |
1427+
ast::OtherRegionTyParamBound(_) => {}
14511428
}
14521429
}
1430+
}
1431+
}
1432+
1433+
fn visit_ty(&mut self, t: &ast::Ty, _: ()) {
1434+
match t.node {
1435+
ast::TyPath(ref p, _, path_id) => self.check_path(p, path_id),
14531436
_ => {}
14541437
}
14551438
visit::walk_ty(self, t, ())
@@ -1535,13 +1518,13 @@ pub fn check_crate(tcx: &ty::ctxt,
15351518

15361519
let EmbargoVisitor { exported_items, public_items, .. } = visitor;
15371520

1538-
{
1521+
if !tcx.sess.features.visible_private_types.get() {
15391522
let mut visitor = VisiblePrivateTypesVisitor {
15401523
tcx: tcx,
15411524
exported_items: &exported_items,
1542-
public_items: &public_items
15431525
};
15441526
visit::walk_crate(&mut visitor, krate, ());
15451527
}
1528+
15461529
return (exported_items, public_items);
15471530
}

src/librustc/middle/resolve.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use std::uint;
4444
// Definition mapping
4545
pub type DefMap = RefCell<NodeMap<Def>>;
4646

47-
struct binding_info {
47+
pub struct binding_info {
4848
span: Span,
4949
binding_mode: BindingMode,
5050
}

src/librustc/middle/resolve_lifetime.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct LifetimeContext<'a> {
5656
named_region_map: NamedRegionMap,
5757
}
5858

59-
enum ScopeChain<'a> {
59+
pub enum ScopeChain<'a> {
6060
/// EarlyScope(i, ['a, 'b, ...], s) extends s with early-bound
6161
/// lifetimes, assigning indexes 'a => i, 'b => i+1, ... etc.
6262
EarlyScope(subst::ParamSpace, &'a Vec<ast::LifetimeDef>, Scope<'a>),
@@ -69,7 +69,7 @@ enum ScopeChain<'a> {
6969
RootScope
7070
}
7171

72-
type Scope<'a> = &'a ScopeChain<'a>;
72+
pub type Scope<'a> = &'a ScopeChain<'a>;
7373

7474
pub fn krate(sess: &Session, krate: &ast::Crate) -> NamedRegionMap {
7575
let mut ctxt = LifetimeContext {

src/librustc/middle/typeck/infer/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1429,7 +1429,7 @@ impl<'a> ErrorReportingHelpers for InferCtxt<'a> {
14291429
}
14301430
}
14311431

1432-
trait Resolvable {
1432+
pub trait Resolvable {
14331433
fn resolve(&self, infcx: &InferCtxt) -> Self;
14341434
fn contains_error(&self) -> bool;
14351435
}

src/librustc/middle/typeck/infer/lattice.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use util::ppaux::Repr;
4545

4646
use std::collections::HashMap;
4747

48-
trait LatticeValue : Clone + Repr + PartialEq {
48+
pub trait LatticeValue : Clone + Repr + PartialEq {
4949
fn sub(cf: CombineFields, a: &Self, b: &Self) -> ures;
5050
fn lub(cf: CombineFields, a: &Self, b: &Self) -> cres<Self>;
5151
fn glb(cf: CombineFields, a: &Self, b: &Self) -> cres<Self>;

src/librustc/middle/typeck/variance.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,11 @@ pub fn infer_variance(tcx: &ty::ctxt,
230230
* a variable.
231231
*/
232232

233-
type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
233+
pub type VarianceTermPtr<'a> = &'a VarianceTerm<'a>;
234234

235-
struct InferredIndex(uint);
235+
pub struct InferredIndex(uint);
236236

237-
enum VarianceTerm<'a> {
237+
pub enum VarianceTerm<'a> {
238238
ConstantTerm(ty::Variance),
239239
TransformTerm(VarianceTermPtr<'a>, VarianceTermPtr<'a>),
240240
InferredTerm(InferredIndex),

src/librustc_llvm/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pub enum AttributeSet {
140140
FunctionIndex = !0
141141
}
142142

143-
trait AttrHelper {
143+
pub trait AttrHelper {
144144
fn apply_llfn(&self, idx: c_uint, llfn: ValueRef);
145145
fn apply_callsite(&self, idx: c_uint, callsite: ValueRef);
146146
}

0 commit comments

Comments
 (0)