1 #![feature(decl_macro)]
2 #![allow(private_in_public)]
3 
4 mod m {
priv_fn()5     fn priv_fn() {}
6     static PRIV_STATIC: u8 = 0;
7     enum PrivEnum { Variant }
8     pub enum PubEnum { Variant }
method()9     trait PrivTrait { fn method() {} }
10     impl PrivTrait for u8 {}
method()11     pub trait PubTrait { fn method() {} }
12     impl PubTrait for u8 {}
13     struct PrivTupleStruct(u8);
14     pub struct PubTupleStruct(u8);
method()15     impl PubTupleStruct { fn method() {} }
16 
17     #[derive(Clone, Copy)]
18     struct Priv;
19     pub type Alias = Priv;
20     pub struct Pub<T = Alias>(pub T);
21 
22     impl Pub<Priv> {
static_method()23         pub fn static_method() {}
24         pub const INHERENT_ASSOC_CONST: u8 = 0;
25     }
26     impl<T> Pub<T> {
static_method_generic_self()27         pub fn static_method_generic_self() {}
28         pub const INHERENT_ASSOC_CONST_GENERIC_SELF: u8 = 0;
29     }
30     impl Pub<u8> {
priv_method(&self)31         fn priv_method(&self) {}
method_with_substs<T>(&self)32         pub fn method_with_substs<T>(&self) {}
method_with_priv_params(&self, _: Priv)33         pub fn method_with_priv_params(&self, _: Priv) {}
34     }
35     impl TraitWithAssocConst for Priv {}
36     impl TraitWithAssocTy for Priv { type AssocTy = u8; }
37 
38     pub macro m() {
39         priv_fn; //~ ERROR type `fn() {priv_fn}` is private
40         PRIV_STATIC; // OK, not cross-crate
41         PrivEnum::Variant; //~ ERROR type `PrivEnum` is private
42         PubEnum::Variant; // OK
43         <u8 as PrivTrait>::method; //~ ERROR type `fn() {<u8 as PrivTrait>::method}` is private
44         <u8 as PubTrait>::method; // OK
45         PrivTupleStruct;
46         //~^ ERROR type `fn(u8) -> PrivTupleStruct {PrivTupleStruct}` is private
47         PubTupleStruct;
48         //~^ ERROR type `fn(u8) -> PubTupleStruct {PubTupleStruct}` is private
49         Pub(0u8).priv_method();
50         //~^ ERROR type `for<'r> fn(&'r Pub<u8>) {Pub::<u8>::priv_method}` is private
51     }
52 
53     trait Trait {}
54     pub trait TraitWithTyParam<T> {}
pub_method()55     pub trait TraitWithTyParam2<T> { fn pub_method() {} }
56     pub trait TraitWithAssocTy { type AssocTy; }
57     pub trait TraitWithAssocConst { const TRAIT_ASSOC_CONST: u8 = 0; }
58     impl Trait for u8 {}
59     impl<T> TraitWithTyParam<T> for u8 {}
60     impl TraitWithTyParam2<Priv> for u8 {}
61     impl TraitWithAssocTy for u8 { type AssocTy = Priv; }
62     //~^ ERROR private type `Priv` in public interface
63 
leak_anon1() -> impl Trait + 'static64     pub fn leak_anon1() -> impl Trait + 'static { 0 }
leak_anon2() -> impl TraitWithTyParam<Alias>65     pub fn leak_anon2() -> impl TraitWithTyParam<Alias> { 0 }
leak_anon3() -> impl TraitWithAssocTy<AssocTy = Alias>66     pub fn leak_anon3() -> impl TraitWithAssocTy<AssocTy = Alias> { 0 }
67 
leak_dyn1() -> Box<dyn Trait + 'static>68     pub fn leak_dyn1() -> Box<dyn Trait + 'static> { Box::new(0) }
leak_dyn2() -> Box<dyn TraitWithTyParam<Alias>>69     pub fn leak_dyn2() -> Box<dyn TraitWithTyParam<Alias>> { Box::new(0) }
leak_dyn3() -> Box<dyn TraitWithAssocTy<AssocTy = Alias>>70     pub fn leak_dyn3() -> Box<dyn TraitWithAssocTy<AssocTy = Alias>> { Box::new(0) }
71 }
72 
73 mod adjust {
74     // Construct a chain of derefs with a private type in the middle
75     use std::ops::Deref;
76 
77     pub struct S1;
78     struct S2;
79     pub type S2Alias = S2;
80     pub struct S3;
81 
82     impl Deref for S1 {
83         type Target = S2Alias; //~ ERROR private type `S2` in public interface
deref(&self) -> &Self::Target84         fn deref(&self) -> &Self::Target { loop {} }
85     }
86     impl Deref for S2 {
87         type Target = S3;
deref(&self) -> &Self::Target88         fn deref(&self) -> &Self::Target { loop {} }
89     }
90 
91     impl S3 {
method_s3(&self)92         pub fn method_s3(&self) {}
93     }
94 }
95 
main()96 fn main() {
97     let _: m::Alias; //~ ERROR type `Priv` is private
98                      //~^ ERROR type `Priv` is private
99     let _: <m::Alias as m::TraitWithAssocTy>::AssocTy; //~ ERROR type `Priv` is private
100     m::Alias {}; //~ ERROR type `Priv` is private
101     m::Pub { 0: m::Alias {} }; //~ ERROR type `Priv` is private
102     m::Pub { 0: loop {} }; // OK, `m::Pub` is in value context, so it means Pub<_>, not Pub<Priv>
103     m::Pub::static_method; //~ ERROR type `Priv` is private
104     m::Pub::INHERENT_ASSOC_CONST; //~ ERROR type `Priv` is private
105     m::Pub(0u8).method_with_substs::<m::Alias>(); //~ ERROR type `Priv` is private
106     m::Pub(0u8).method_with_priv_params(loop{}); //~ ERROR type `Priv` is private
107     <m::Alias as m::TraitWithAssocConst>::TRAIT_ASSOC_CONST; //~ ERROR type `Priv` is private
108     <m::Pub<m::Alias>>::INHERENT_ASSOC_CONST; //~ ERROR type `Priv` is private
109     <m::Pub<m::Alias>>::INHERENT_ASSOC_CONST_GENERIC_SELF; //~ ERROR type `Priv` is private
110     <m::Pub<m::Alias>>::static_method_generic_self; //~ ERROR type `Priv` is private
111     use m::TraitWithTyParam2;
112     u8::pub_method; //~ ERROR type `Priv` is private
113 
114     adjust::S1.method_s3(); //~ ERROR type `S2` is private
115 
116     m::m!();
117 
118     m::leak_anon1(); //~ ERROR trait `Trait` is private
119     m::leak_anon2(); //~ ERROR type `Priv` is private
120     m::leak_anon3(); //~ ERROR type `Priv` is private
121 
122     m::leak_dyn1(); //~ ERROR trait `Trait` is private
123     m::leak_dyn2(); //~ ERROR type `Priv` is private
124     m::leak_dyn3(); //~ ERROR type `Priv` is private
125 
126     // Check that messages are not duplicated for various kinds of assignments
127     let a = m::Alias {}; //~ ERROR type `Priv` is private
128     let mut b = a; //~ ERROR type `Priv` is private
129     b = a; //~ ERROR type `Priv` is private
130     match a { //~ ERROR type `Priv` is private
131         _ => {}
132     }
133 }
134