rustc: implement a lint for publicly visible private types.

These are types that are in exported type signatures, but are not
exported themselves, e.g.

    struct Foo { ... }

    pub fn bar() -> Foo { ... }

will warn about the Foo.

Such types are not listed in documentation, and cannot be named outside
the crate in which they are declared, which is very user-unfriendly.

cc #10573
This commit is contained in:
Huon Wilson 2014-02-27 18:33:03 +11:00
parent 31e9c947a3
commit 859277dfdb
5 changed files with 400 additions and 5 deletions

View file

@ -11,6 +11,7 @@
#[no_std];
#[allow(unused_variable)];
#[allow(non_camel_case_types)];
#[allow(visible_private_types)];
#[deny(dead_code)];
#[crate_type="lib"];

View file

@ -0,0 +1,129 @@
// 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(struct_variant)];
#[deny(visible_private_types)];
#[allow(dead_code)];
#[crate_type="lib"];
struct Private<T>;
pub struct Public<T>;
impl Private<Public<int>> {
pub fn a(&self) -> Private<int> { fail!() }
fn b(&self) -> Private<int> { fail!() }
pub fn c() -> Private<int> { fail!() }
fn d() -> Private<int> { fail!() }
}
impl Private<int> {
pub fn e(&self) -> Private<int> { fail!() }
fn f(&self) -> Private<int> { fail!() }
}
impl Public<Private<int>> {
pub fn a(&self) -> Private<int> { fail!() }
fn b(&self) -> Private<int> { fail!() }
pub fn c() -> Private<int> { fail!() } //~ ERROR private type in exported type signature
fn d() -> Private<int> { fail!() }
}
impl Public<int> {
pub fn e(&self) -> Private<int> { fail!() } //~ ERROR private type in exported type signature
fn f(&self) -> Private<int> { fail!() }
}
pub fn x(_: Private<int>) {} //~ ERROR private type in exported type signature
fn y(_: Private<int>) {}
pub struct Foo {
x: Private<int>, //~ ERROR private type in exported type signature
priv y: Private<int>
}
struct Bar {
x: Private<int>,
}
pub enum Baz {
Baz1(Private<int>), //~ ERROR private type in exported type signature
Baz2 {
x: Private<int>, //~ ERROR private type in exported type signature
priv y: Private<int>
},
priv Baz3(Private<int>),
priv Baz4 {
x: Private<int>,
}
}
enum Qux {
Qux1(Private<int>),
Qux2 {
x: Private<int>,
}
}
pub trait PubTrait {
fn foo(&self) -> Private<int> { fail!( )} //~ ERROR private type in exported type signature
fn bar(&self) -> Private<int>; //~ ERROR private type in exported type signature
fn baz() -> Private<int>; //~ ERROR private type in exported type signature
}
impl PubTrait for Public<int> {
fn bar(&self) -> Private<int> { fail!() }
fn baz() -> Private<int> { fail!() }
}
impl PubTrait for Public<Private<int>> {
fn bar(&self) -> Private<int> { fail!() }
fn baz() -> Private<int> { fail!() }
}
impl PubTrait for Private<int> {
fn bar(&self) -> Private<int> { fail!() }
fn baz() -> Private<int> { fail!() }
}
impl PubTrait for (Private<int>,) {
fn bar(&self) -> Private<int> { fail!() }
fn baz() -> Private<int> { fail!() }
}
trait PrivTrait {
fn foo(&self) -> Private<int> { fail!( )}
fn bar(&self) -> Private<int>;
}
impl PrivTrait for Private<int> {
fn bar(&self) -> Private<int> { fail!() }
}
impl PrivTrait for (Private<int>,) {
fn bar(&self) -> Private<int> { fail!() }
}
pub trait ParamTrait<T> {
fn foo() -> T;
}
impl ParamTrait<Private<int>> //~ ERROR private type in exported type signature
for Public<int> {
fn foo() -> Private<int> { fail!() }
}
impl ParamTrait<Private<int>> for Private<int> {
fn foo() -> Private<int> { fail!( )}
}
impl<T: ParamTrait<Private<int>>> //~ ERROR private type in exported type signature
ParamTrait<T> for Public<i8> {
fn foo() -> T { fail!() }
}