Auto merge of #29973 - petrochenkov:privinpub, r=nikomatsakis
Some notes: This patch enforces the rules from [RFC 136](https://github.com/rust-lang/rfcs/blob/master/text/0136-no-privates-in-public.md) and makes "private in public" a module-level concept and not crate-level. Only `pub` annotations are used by the new algorithm, crate-level exported node set produced by `EmbargoVisitor` is not used. The error messages are tweaked accordingly and don't use the word "exported" to avoid confusing people (https://github.com/rust-lang/rust/issues/29668). The old algorithm tried to be extra smart with impls, but it mostly led to unpredictable behavior and bugs like https://github.com/rust-lang/rust/issues/28325. The new algorithm tries to be as simple as possible - an impl is considered public iff its type is public and its trait is public (if presents). A type or trait is considered public if all its components are public, [complications](https://internals.rust-lang.org/t/limits-of-type-inference-smartness/2919) with private types leaking to other crates/modules through trait impls and type inference are deliberately ignored so far. The new algorithm is not recursive and uses the nice new facility `Crate::visit_all_items`! Obsolete pre-1.0 feature `visible_private_types` is removed. This is a [breaking-change]. The two main vectors of breakage are type aliases (https://github.com/rust-lang/rust/issues/28450) and impls (https://github.com/rust-lang/rust/issues/28325). I need some statistics from a crater run (cc @alexcrichton) to decide on the breakage mitigation strategy. UPDATE: All the new errors are reported as warnings controlled by a lint `private_in_public` and lint group `future_incompatible`, but the intent is to make them hard errors eventually. Closes https://github.com/rust-lang/rust/issues/28325 Closes https://github.com/rust-lang/rust/issues/28450 Closes https://github.com/rust-lang/rust/issues/29524 Closes https://github.com/rust-lang/rust/issues/29627 Closes https://github.com/rust-lang/rust/issues/29668 Closes https://github.com/rust-lang/rust/issues/30055 r? @nikomatsakis
This commit is contained in:
commit
ef91cdb140
30 changed files with 808 additions and 320 deletions
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
use std::marker;
|
||||
|
||||
struct arc_destruct<T: Sync> {
|
||||
pub struct arc_destruct<T: Sync> {
|
||||
_data: isize,
|
||||
_marker: marker::PhantomData<T>
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ fn init() -> arc_destruct<context_res> {
|
|||
arc(context_res())
|
||||
}
|
||||
|
||||
struct context_res {
|
||||
pub struct context_res {
|
||||
ctx : isize,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use foo::NoResult; // Through a re-export
|
|||
mod foo {
|
||||
pub use self::MyEnum::NoResult;
|
||||
|
||||
enum MyEnum {
|
||||
pub enum MyEnum {
|
||||
Result,
|
||||
NoResult
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use std::any::TypeId;
|
|||
trait Private<P, R> {
|
||||
fn call(&self, p: P, r: R);
|
||||
}
|
||||
pub trait Public: Private< //~ ERROR private trait in exported type parameter bound
|
||||
pub trait Public: Private< //~ ERROR private trait in public interface
|
||||
<Self as Public>::P,
|
||||
<Self as Public>::R
|
||||
> {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct UsedStruct1 {
|
|||
}
|
||||
struct UsedStruct2(isize);
|
||||
struct UsedStruct3;
|
||||
struct UsedStruct4;
|
||||
pub struct UsedStruct4;
|
||||
// this struct is never used directly, but its method is, so we don't want
|
||||
// to warn it
|
||||
struct SemiUsedStruct;
|
||||
|
|
|
|||
|
|
@ -1,123 +0,0 @@
|
|||
// 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.
|
||||
|
||||
#![allow(dead_code)]
|
||||
#![crate_type="lib"]
|
||||
|
||||
use std::marker;
|
||||
|
||||
struct Private<T>(marker::PhantomData<T>);
|
||||
pub struct Public<T>(marker::PhantomData<T>);
|
||||
|
||||
impl Private<Public<isize>> {
|
||||
pub fn a(&self) -> Private<isize> { panic!() }
|
||||
fn b(&self) -> Private<isize> { panic!() }
|
||||
|
||||
pub fn c() -> Private<isize> { panic!() }
|
||||
fn d() -> Private<isize> { panic!() }
|
||||
}
|
||||
impl Private<isize> {
|
||||
pub fn e(&self) -> Private<isize> { panic!() }
|
||||
fn f(&self) -> Private<isize> { panic!() }
|
||||
}
|
||||
|
||||
impl Public<Private<isize>> {
|
||||
pub fn a(&self) -> Private<isize> { panic!() }
|
||||
fn b(&self) -> Private<isize> { panic!() }
|
||||
|
||||
pub fn c() -> Private<isize> { panic!() } //~ ERROR private type in exported type signature
|
||||
fn d() -> Private<isize> { panic!() }
|
||||
}
|
||||
impl Public<isize> {
|
||||
pub fn e(&self) -> Private<isize> { panic!() } //~ ERROR private type in exported type signature
|
||||
fn f(&self) -> Private<isize> { panic!() }
|
||||
}
|
||||
|
||||
pub fn x(_: Private<isize>) {} //~ ERROR private type in exported type signature
|
||||
|
||||
fn y(_: Private<isize>) {}
|
||||
|
||||
|
||||
pub struct Foo {
|
||||
pub x: Private<isize>, //~ ERROR private type in exported type signature
|
||||
y: Private<isize>
|
||||
}
|
||||
|
||||
struct Bar {
|
||||
x: Private<isize>,
|
||||
}
|
||||
|
||||
pub enum Baz {
|
||||
Baz1(Private<isize>), //~ ERROR private type in exported type signature
|
||||
Baz2 {
|
||||
y: Private<isize> //~ ERROR private type in exported type signature
|
||||
},
|
||||
}
|
||||
|
||||
enum Qux {
|
||||
Qux1(Private<isize>),
|
||||
Qux2 {
|
||||
x: Private<isize>,
|
||||
}
|
||||
}
|
||||
|
||||
pub trait PubTrait {
|
||||
fn foo(&self) -> Private<isize> { panic!( )} //~ ERROR private type in exported type signature
|
||||
fn bar(&self) -> Private<isize>; //~ ERROR private type in exported type signature
|
||||
fn baz() -> Private<isize>; //~ ERROR private type in exported type signature
|
||||
}
|
||||
|
||||
impl PubTrait for Public<isize> {
|
||||
fn bar(&self) -> Private<isize> { panic!() }
|
||||
fn baz() -> Private<isize> { panic!() }
|
||||
}
|
||||
impl PubTrait for Public<Private<isize>> {
|
||||
fn bar(&self) -> Private<isize> { panic!() }
|
||||
fn baz() -> Private<isize> { panic!() }
|
||||
}
|
||||
|
||||
impl PubTrait for Private<isize> {
|
||||
fn bar(&self) -> Private<isize> { panic!() }
|
||||
fn baz() -> Private<isize> { panic!() }
|
||||
}
|
||||
impl PubTrait for (Private<isize>,) {
|
||||
fn bar(&self) -> Private<isize> { panic!() }
|
||||
fn baz() -> Private<isize> { panic!() }
|
||||
}
|
||||
|
||||
|
||||
trait PrivTrait {
|
||||
fn foo(&self) -> Private<isize> { panic!( )}
|
||||
fn bar(&self) -> Private<isize>;
|
||||
}
|
||||
impl PrivTrait for Private<isize> {
|
||||
fn bar(&self) -> Private<isize> { panic!() }
|
||||
}
|
||||
impl PrivTrait for (Private<isize>,) {
|
||||
fn bar(&self) -> Private<isize> { panic!() }
|
||||
}
|
||||
|
||||
pub trait ParamTrait<T> {
|
||||
fn foo() -> T;
|
||||
}
|
||||
|
||||
impl ParamTrait<Private<isize>> //~ ERROR private type in exported type signature
|
||||
for Public<isize> {
|
||||
fn foo() -> Private<isize> { panic!() }
|
||||
}
|
||||
|
||||
impl ParamTrait<Private<isize>> for Private<isize> {
|
||||
fn foo() -> Private<isize> { panic!( )}
|
||||
}
|
||||
|
||||
impl<T: ParamTrait<Private<isize>>> //~ ERROR private type in exported type signature
|
||||
ParamTrait<T> for Public<i8> {
|
||||
fn foo() -> T { panic!() }
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// Test that we properly check for private types in public signatures, even
|
||||
// inside a private module (#22261).
|
||||
|
||||
mod a {
|
||||
struct Priv;
|
||||
|
||||
pub fn expose_a() -> Priv { //~Error: private type in exported type signature
|
||||
panic!();
|
||||
}
|
||||
|
||||
mod b {
|
||||
pub fn expose_b() -> super::Priv { //~Error: private type in exported type signature
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {}
|
||||
|
|
@ -8,16 +8,26 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// pretty-expanded FIXME #23616
|
||||
mod m1 {
|
||||
#![deny(private_in_public)]
|
||||
|
||||
#![feature(visible_private_types)]
|
||||
pub struct Pub;
|
||||
struct Priv;
|
||||
|
||||
trait Foo { fn dummy(&self) { } }
|
||||
impl Pub {
|
||||
pub fn f() -> Priv {} //~ ERROR private type in public interface
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Bar : Foo {}
|
||||
mod m2 {
|
||||
#![deny(future_incompatible)]
|
||||
|
||||
struct Baz;
|
||||
pub struct Pub;
|
||||
struct Priv;
|
||||
|
||||
pub fn f(_: Baz) {}
|
||||
impl Pub {
|
||||
pub fn f() -> Priv {} //~ ERROR private type in public interface
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
251
src/test/compile-fail/private-in-public-warn.rs
Normal file
251
src/test/compile-fail/private-in-public-warn.rs
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// Private types and traits are not allowed in public interfaces.
|
||||
// This test also ensures that the checks are performed even inside private modules.
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(associated_consts)]
|
||||
#![feature(associated_type_defaults)]
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused_variables)]
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
mod types {
|
||||
struct Priv;
|
||||
pub struct Pub;
|
||||
pub trait PubTr {
|
||||
type Alias;
|
||||
}
|
||||
|
||||
pub type Alias = Priv; //~ WARN private type in public interface
|
||||
pub enum E {
|
||||
V1(Priv), //~ WARN private type in public interface
|
||||
V2 { field: Priv }, //~ WARN private type in public interface
|
||||
}
|
||||
pub trait Tr {
|
||||
const C: Priv = Priv; //~ WARN private type in public interface
|
||||
type Alias = Priv; //~ WARN private type in public interface
|
||||
fn f1(arg: Priv) {} //~ WARN private type in public interface
|
||||
fn f2() -> Priv { panic!() } //~ WARN private type in public interface
|
||||
}
|
||||
extern {
|
||||
pub static ES: Priv; //~ WARN private type in public interface
|
||||
pub fn ef1(arg: Priv); //~ WARN private type in public interface
|
||||
pub fn ef2() -> Priv; //~ WARN private type in public interface
|
||||
}
|
||||
impl PubTr for Pub {
|
||||
type Alias = Priv; //~ WARN private type in public interface
|
||||
}
|
||||
}
|
||||
|
||||
mod traits {
|
||||
trait PrivTr {}
|
||||
pub struct Pub<T>(T);
|
||||
pub trait PubTr {}
|
||||
|
||||
pub type Alias<T: PrivTr> = T; //~ WARN private trait in public interface
|
||||
//~^ WARN trait bounds are not (yet) enforced in type definitions
|
||||
pub trait Tr1: PrivTr {} //~ WARN private trait in public interface
|
||||
pub trait Tr2<T: PrivTr> {} //~ WARN private trait in public interface
|
||||
pub trait Tr3 {
|
||||
type Alias: PrivTr; //~ WARN private trait in public interface
|
||||
fn f<T: PrivTr>(arg: T) {} //~ WARN private trait in public interface
|
||||
}
|
||||
impl<T: PrivTr> Pub<T> {} //~ WARN private trait in public interface
|
||||
impl<T: PrivTr> PubTr for Pub<T> {} //~ WARN private trait in public interface
|
||||
}
|
||||
|
||||
mod traits_where {
|
||||
trait PrivTr {}
|
||||
pub struct Pub<T>(T);
|
||||
pub trait PubTr {}
|
||||
|
||||
pub type Alias<T> where T: PrivTr = T; //~ WARN private trait in public interface
|
||||
pub trait Tr2<T> where T: PrivTr {} //~ WARN private trait in public interface
|
||||
pub trait Tr3 {
|
||||
fn f<T>(arg: T) where T: PrivTr {} //~ WARN private trait in public interface
|
||||
}
|
||||
impl<T> Pub<T> where T: PrivTr {} //~ WARN private trait in public interface
|
||||
impl<T> PubTr for Pub<T> where T: PrivTr {} //~ WARN private trait in public interface
|
||||
}
|
||||
|
||||
mod generics {
|
||||
struct Priv<T = u8>(T);
|
||||
pub struct Pub<T = u8>(T);
|
||||
trait PrivTr<T> {}
|
||||
pub trait PubTr<T> {}
|
||||
|
||||
pub trait Tr1: PrivTr<Pub> {} //~ WARN private trait in public interface
|
||||
pub trait Tr2: PubTr<Priv> {} //~ WARN private type in public interface
|
||||
pub trait Tr3: PubTr<[Priv; 1]> {} //~ WARN private type in public interface
|
||||
pub trait Tr4: PubTr<Pub<Priv>> {} //~ WARN private type in public interface
|
||||
}
|
||||
|
||||
mod impls {
|
||||
struct Priv;
|
||||
pub struct Pub;
|
||||
trait PrivTr {
|
||||
type Alias;
|
||||
}
|
||||
pub trait PubTr {
|
||||
type Alias;
|
||||
}
|
||||
|
||||
impl Priv {
|
||||
pub fn f(arg: Priv) {} // OK
|
||||
}
|
||||
impl PrivTr for Priv {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
impl PubTr for Priv {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
impl PrivTr for Pub {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
impl PubTr for Pub {
|
||||
type Alias = Priv; //~ WARN private type in public interface
|
||||
}
|
||||
}
|
||||
|
||||
mod impls_generics {
|
||||
struct Priv<T = u8>(T);
|
||||
pub struct Pub<T = u8>(T);
|
||||
trait PrivTr<T = u8> {
|
||||
type Alias;
|
||||
}
|
||||
pub trait PubTr<T = u8> {
|
||||
type Alias;
|
||||
}
|
||||
|
||||
impl Priv<Pub> {
|
||||
pub fn f(arg: Priv) {} // OK
|
||||
}
|
||||
impl Pub<Priv> {
|
||||
pub fn f(arg: Priv) {} // OK
|
||||
}
|
||||
impl PrivTr<Pub> for Priv {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
impl PubTr<Priv> for Priv {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
impl PubTr for Priv<Pub> {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
impl PubTr for [Priv; 1] {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
impl PubTr for Pub<Priv> {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
impl PrivTr<Pub> for Pub {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
impl PubTr<Priv> for Pub {
|
||||
type Alias = Priv; // OK
|
||||
}
|
||||
}
|
||||
|
||||
mod aliases_pub {
|
||||
struct Priv;
|
||||
mod m {
|
||||
pub struct Pub1;
|
||||
pub struct Pub2;
|
||||
pub struct Pub3;
|
||||
pub trait PubTr<T = u8> {
|
||||
type Check = u8;
|
||||
}
|
||||
}
|
||||
|
||||
use self::m::Pub1 as PrivUseAlias;
|
||||
use self::m::PubTr as PrivUseAliasTr;
|
||||
type PrivAlias = m::Pub2;
|
||||
trait PrivTr {
|
||||
type AssocAlias = m::Pub3;
|
||||
}
|
||||
impl PrivTr for Priv {}
|
||||
|
||||
pub fn f1(arg: PrivUseAlias) {} // OK
|
||||
|
||||
pub trait Tr1: PrivUseAliasTr {} // OK
|
||||
// This should be OK, if type aliases are substituted
|
||||
pub trait Tr2: PrivUseAliasTr<PrivAlias> {} //~ WARN private type in public interface
|
||||
|
||||
impl PrivAlias {
|
||||
pub fn f(arg: Priv) {} //~ WARN private type in public interface
|
||||
}
|
||||
// This doesn't even parse
|
||||
// impl <Priv as PrivTr>::AssocAlias {
|
||||
// pub fn f(arg: Priv) {} // WARN private type in public interface
|
||||
// }
|
||||
impl PrivUseAliasTr for PrivUseAlias {
|
||||
type Check = Priv; //~ WARN private type in public interface
|
||||
}
|
||||
impl PrivUseAliasTr for PrivAlias {
|
||||
type Check = Priv; //~ WARN private type in public interface
|
||||
}
|
||||
impl PrivUseAliasTr for <Priv as PrivTr>::AssocAlias {
|
||||
type Check = Priv; //~ WARN private type in public interface
|
||||
}
|
||||
}
|
||||
|
||||
mod aliases_priv {
|
||||
struct Priv;
|
||||
|
||||
struct Priv1;
|
||||
struct Priv2;
|
||||
struct Priv3;
|
||||
trait PrivTr1<T = u8> {
|
||||
type Check = u8;
|
||||
}
|
||||
|
||||
use self::Priv1 as PrivUseAlias;
|
||||
use self::PrivTr1 as PrivUseAliasTr;
|
||||
type PrivAlias = Priv2;
|
||||
trait PrivTr {
|
||||
type AssocAlias = Priv3;
|
||||
}
|
||||
impl PrivTr for Priv {}
|
||||
|
||||
pub trait Tr1: PrivUseAliasTr {} //~ WARN private trait in public interface
|
||||
pub trait Tr2: PrivUseAliasTr<PrivAlias> {} //~ WARN private trait in public interface
|
||||
//~^ WARN private type in public interface
|
||||
|
||||
impl PrivUseAlias {
|
||||
pub fn f(arg: Priv) {} // OK
|
||||
}
|
||||
impl PrivAlias {
|
||||
pub fn f(arg: Priv) {} // OK
|
||||
}
|
||||
// This doesn't even parse
|
||||
// impl <Priv as PrivTr>::AssocAlias {
|
||||
// pub fn f(arg: Priv) {} // OK
|
||||
// }
|
||||
impl PrivUseAliasTr for PrivUseAlias {
|
||||
type Check = Priv; // OK
|
||||
}
|
||||
impl PrivUseAliasTr for PrivAlias {
|
||||
type Check = Priv; // OK
|
||||
}
|
||||
impl PrivUseAliasTr for <Priv as PrivTr>::AssocAlias {
|
||||
type Check = Priv; // OK
|
||||
}
|
||||
}
|
||||
|
||||
mod aliases_params {
|
||||
struct Priv;
|
||||
type PrivAliasGeneric<T = Priv> = T;
|
||||
type Result<T> = ::std::result::Result<T, Priv>;
|
||||
}
|
||||
|
||||
#[rustc_error]
|
||||
fn main() {} //~ ERROR compilation successful
|
||||
152
src/test/compile-fail/private-in-public.rs
Normal file
152
src/test/compile-fail/private-in-public.rs
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
// Copyright 2015 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.
|
||||
|
||||
// Private types and traits are not allowed in public interfaces.
|
||||
// This test also ensures that the checks are performed even inside private modules.
|
||||
|
||||
#![feature(associated_consts)]
|
||||
#![feature(associated_type_defaults)]
|
||||
|
||||
mod types {
|
||||
struct Priv;
|
||||
pub struct Pub;
|
||||
pub trait PubTr {
|
||||
type Alias;
|
||||
}
|
||||
|
||||
pub const C: Priv = Priv; //~ ERROR private type in public interface
|
||||
pub static S: Priv = Priv; //~ ERROR private type in public interface
|
||||
pub fn f1(arg: Priv) {} //~ ERROR private type in public interface
|
||||
pub fn f2() -> Priv { panic!() } //~ ERROR private type in public interface
|
||||
pub struct S1(pub Priv); //~ ERROR private type in public interface
|
||||
pub struct S2 { pub field: Priv } //~ ERROR private type in public interface
|
||||
impl Pub {
|
||||
pub const C: Priv = Priv; //~ ERROR private type in public interface
|
||||
pub fn f1(arg: Priv) {} //~ ERROR private type in public interface
|
||||
pub fn f2() -> Priv { panic!() } //~ ERROR private type in public interface
|
||||
}
|
||||
}
|
||||
|
||||
mod traits {
|
||||
trait PrivTr {}
|
||||
pub struct Pub<T>(T);
|
||||
pub trait PubTr {}
|
||||
|
||||
pub enum E<T: PrivTr> { V(T) } //~ ERROR private trait in public interface
|
||||
pub fn f<T: PrivTr>(arg: T) {} //~ ERROR private trait in public interface
|
||||
pub struct S1<T: PrivTr>(T); //~ ERROR private trait in public interface
|
||||
impl<T: PrivTr> Pub<T> {
|
||||
pub fn f<U: PrivTr>(arg: U) {} //~ ERROR private trait in public interface
|
||||
}
|
||||
}
|
||||
|
||||
mod traits_where {
|
||||
trait PrivTr {}
|
||||
pub struct Pub<T>(T);
|
||||
pub trait PubTr {}
|
||||
|
||||
pub enum E<T> where T: PrivTr { V(T) } //~ ERROR private trait in public interface
|
||||
pub fn f<T>(arg: T) where T: PrivTr {} //~ ERROR private trait in public interface
|
||||
pub struct S1<T>(T) where T: PrivTr; //~ ERROR private trait in public interface
|
||||
impl<T> Pub<T> where T: PrivTr {
|
||||
pub fn f<U>(arg: U) where U: PrivTr {} //~ ERROR private trait in public interface
|
||||
}
|
||||
}
|
||||
|
||||
mod generics {
|
||||
struct Priv<T = u8>(T);
|
||||
pub struct Pub<T = u8>(T);
|
||||
trait PrivTr<T> {}
|
||||
pub trait PubTr<T> {}
|
||||
|
||||
pub fn f1(arg: [Priv; 1]) {} //~ ERROR private type in public interface
|
||||
pub fn f2(arg: Pub<Priv>) {} //~ ERROR private type in public interface
|
||||
pub fn f3(arg: Priv<Pub>) {} //~ ERROR private type in public interface
|
||||
}
|
||||
|
||||
mod impls {
|
||||
struct Priv;
|
||||
pub struct Pub;
|
||||
trait PrivTr {
|
||||
type Alias;
|
||||
}
|
||||
pub trait PubTr {
|
||||
type Alias;
|
||||
}
|
||||
|
||||
impl Pub {
|
||||
pub fn f(arg: Priv) {} //~ ERROR private type in public interface
|
||||
}
|
||||
}
|
||||
|
||||
mod aliases_pub {
|
||||
struct Priv;
|
||||
mod m {
|
||||
pub struct Pub1;
|
||||
pub struct Pub2;
|
||||
pub struct Pub3;
|
||||
pub trait PubTr<T = u8> {
|
||||
type Check = u8;
|
||||
}
|
||||
}
|
||||
|
||||
use self::m::Pub1 as PrivUseAlias;
|
||||
use self::m::PubTr as PrivUseAliasTr;
|
||||
type PrivAlias = m::Pub2;
|
||||
trait PrivTr {
|
||||
type AssocAlias = m::Pub3;
|
||||
}
|
||||
impl PrivTr for Priv {}
|
||||
|
||||
// This should be OK, if type aliases are substituted
|
||||
pub fn f2(arg: PrivAlias) {} //~ ERROR private type in public interface
|
||||
// This should be OK, but associated type aliases are not substituted yet
|
||||
pub fn f3(arg: <Priv as PrivTr>::AssocAlias) {} //~ ERROR private type in public interface
|
||||
|
||||
impl PrivUseAlias {
|
||||
pub fn f(arg: Priv) {} //~ ERROR private type in public interface
|
||||
}
|
||||
}
|
||||
|
||||
mod aliases_priv {
|
||||
struct Priv;
|
||||
|
||||
struct Priv1;
|
||||
struct Priv2;
|
||||
struct Priv3;
|
||||
trait PrivTr1<T = u8> {
|
||||
type Check = u8;
|
||||
}
|
||||
|
||||
use self::Priv1 as PrivUseAlias;
|
||||
use self::PrivTr1 as PrivUseAliasTr;
|
||||
type PrivAlias = Priv2;
|
||||
trait PrivTr {
|
||||
type AssocAlias = Priv3;
|
||||
}
|
||||
impl PrivTr for Priv {}
|
||||
|
||||
pub fn f1(arg: PrivUseAlias) {} //~ ERROR private type in public interface
|
||||
pub fn f2(arg: PrivAlias) {} //~ ERROR private type in public interface
|
||||
pub fn f3(arg: <Priv as PrivTr>::AssocAlias) {} //~ ERROR private type in public interface
|
||||
}
|
||||
|
||||
mod aliases_params {
|
||||
struct Priv;
|
||||
type PrivAliasGeneric<T = Priv> = T;
|
||||
type Result<T> = ::std::result::Result<T, Priv>;
|
||||
|
||||
// This should be OK, if type aliases are substituted
|
||||
pub fn f1(arg: PrivAliasGeneric<u8>) {} //~ ERROR private type in public interface
|
||||
pub fn f2(arg: PrivAliasGeneric) {} //~ ERROR private type in public interface
|
||||
pub fn f3(arg: Result<u8>) {} //~ ERROR private type in public interface
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -8,34 +8,26 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub struct PublicType;
|
||||
struct PrivateType;
|
||||
#![feature(rustc_attrs)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub trait PublicTrait {
|
||||
type Item;
|
||||
mod m1 {
|
||||
pub use ::E::V; //~ WARN variant `V` is private, and cannot be reexported
|
||||
}
|
||||
|
||||
trait PrivateTrait {
|
||||
type Item;
|
||||
mod m2 {
|
||||
pub use ::E::{V}; //~ WARN variant `V` is private, and cannot be reexported
|
||||
}
|
||||
|
||||
impl PublicTrait for PublicType {
|
||||
type Item = PrivateType; //~ ERROR private type in exported type signature
|
||||
mod m3 {
|
||||
pub use ::E::V::{self}; //~ WARN variant `V` is private, and cannot be reexported
|
||||
}
|
||||
|
||||
// OK
|
||||
impl PublicTrait for PrivateType {
|
||||
type Item = PrivateType;
|
||||
mod m4 {
|
||||
pub use ::E::*; //~ WARN variant `V` is private, and cannot be reexported
|
||||
}
|
||||
|
||||
// OK
|
||||
impl PrivateTrait for PublicType {
|
||||
type Item = PrivateType;
|
||||
}
|
||||
enum E { V }
|
||||
|
||||
// OK
|
||||
impl PrivateTrait for PrivateType {
|
||||
type Item = PrivateType;
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
#[rustc_error]
|
||||
fn main() {} //~ ERROR compilation successful
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
// 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 {
|
||||
fn dummy(&self) { }
|
||||
}
|
||||
|
||||
pub fn f<
|
||||
T
|
||||
: Foo //~ ERROR private trait in exported type parameter bound
|
||||
>() {}
|
||||
|
||||
pub fn g<T>() where
|
||||
T
|
||||
: Foo //~ ERROR private trait in exported type parameter bound
|
||||
{}
|
||||
|
||||
pub struct S;
|
||||
|
||||
impl S {
|
||||
pub fn f<
|
||||
T
|
||||
: Foo //~ ERROR private trait in exported type parameter bound
|
||||
>() {}
|
||||
|
||||
pub fn g<T>() where
|
||||
T
|
||||
: Foo //~ ERROR private trait in exported type parameter bound
|
||||
{}
|
||||
}
|
||||
|
||||
pub struct S1<
|
||||
T
|
||||
: Foo //~ ERROR private trait in exported type parameter bound
|
||||
> {
|
||||
x: T
|
||||
}
|
||||
|
||||
pub struct S2<T> where
|
||||
T
|
||||
: Foo //~ ERROR private trait in exported type parameter bound
|
||||
{
|
||||
x: T
|
||||
}
|
||||
|
||||
pub enum E1<
|
||||
T
|
||||
: Foo //~ ERROR private trait in exported type parameter bound
|
||||
> {
|
||||
V1(T)
|
||||
}
|
||||
|
||||
pub enum E2<T> where
|
||||
T
|
||||
: Foo //~ ERROR private trait in exported type parameter bound
|
||||
{
|
||||
V2(T)
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -182,7 +182,7 @@ use self::Enum1::{Variant1, Variant2};
|
|||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
|
||||
struct Struct1;
|
||||
pub struct Struct1;
|
||||
struct GenericStruct<T1, T2>(PhantomData<(T1,T2)>);
|
||||
|
||||
enum Enum1 {
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@
|
|||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
struct DeterministicHasher;
|
||||
struct RandomHasher;
|
||||
pub struct DeterministicHasher;
|
||||
pub struct RandomHasher;
|
||||
|
||||
|
||||
struct MyHashMap<K, V, H=DeterministicHasher> {
|
||||
pub struct MyHashMap<K, V, H=DeterministicHasher> {
|
||||
data: PhantomData<(K, V, H)>
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
trait Test { type T; }
|
||||
pub trait Test { type T; }
|
||||
|
||||
impl Test for u32 {
|
||||
type T = i32;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
|
|
@ -8,10 +8,18 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
trait Foo {
|
||||
fn dummy(&self) { }
|
||||
// Functions can return unnameable types
|
||||
|
||||
mod m1 {
|
||||
mod m2 {
|
||||
#[derive(Debug)]
|
||||
pub struct A;
|
||||
}
|
||||
use self::m2::A;
|
||||
pub fn x() -> A { A }
|
||||
}
|
||||
|
||||
pub trait Bar : Foo {} //~ ERROR private trait in exported type
|
||||
|
||||
fn main() {}
|
||||
fn main() {
|
||||
let x = m1::x();
|
||||
println!("{:?}", x);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue