summaryrefslogtreecommitdiffstats
path: root/src/test/ui/privacy/private-inferred-type.rs
blob: b083a3970d6b9518c73fd2c07d29563e7ac86c46 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#![feature(decl_macro)]
#![allow(private_in_public)]

mod m {
    fn priv_fn() {}
    static PRIV_STATIC: u8 = 0;
    enum PrivEnum { Variant }
    pub enum PubEnum { Variant }
    trait PrivTrait { fn method() {} }
    impl PrivTrait for u8 {}
    pub trait PubTrait { fn method() {} }
    impl PubTrait for u8 {}
    struct PrivTupleStruct(u8);
    pub struct PubTupleStruct(u8);
    impl PubTupleStruct { fn method() {} }

    #[derive(Clone, Copy)]
    struct Priv;
    pub type Alias = Priv;
    pub struct Pub<T = Alias>(pub T);

    impl Pub<Priv> {
        pub fn static_method() {}
        pub const INHERENT_ASSOC_CONST: u8 = 0;
    }
    impl<T> Pub<T> {
        pub fn static_method_generic_self() {}
        pub const INHERENT_ASSOC_CONST_GENERIC_SELF: u8 = 0;
    }
    impl Pub<u8> {
        fn priv_method(&self) {}
        pub fn method_with_substs<T>(&self) {}
        pub fn method_with_priv_params(&self, _: Priv) {}
    }
    impl TraitWithAssocConst for Priv {}
    impl TraitWithAssocTy for Priv { type AssocTy = u8; }

    pub macro m() {
        priv_fn; //~ ERROR type `fn() {priv_fn}` is private
        PRIV_STATIC; // OK, not cross-crate
        PrivEnum::Variant; //~ ERROR type `PrivEnum` is private
        PubEnum::Variant; // OK
        <u8 as PrivTrait>::method; //~ ERROR type `fn() {<u8 as PrivTrait>::method}` is private
        <u8 as PubTrait>::method; // OK
        PrivTupleStruct;
        //~^ ERROR type `fn(u8) -> PrivTupleStruct {PrivTupleStruct}` is private
        PubTupleStruct;
        //~^ ERROR type `fn(u8) -> PubTupleStruct {PubTupleStruct}` is private
        Pub(0u8).priv_method();
        //~^ ERROR type `for<'r> fn(&'r Pub<u8>) {Pub::<u8>::priv_method}` is private
    }

    trait Trait {}
    pub trait TraitWithTyParam<T> {}
    pub trait TraitWithTyParam2<T> { fn pub_method() {} }
    pub trait TraitWithAssocTy { type AssocTy; }
    pub trait TraitWithAssocConst { const TRAIT_ASSOC_CONST: u8 = 0; }
    impl Trait for u8 {}
    impl<T> TraitWithTyParam<T> for u8 {}
    impl TraitWithTyParam2<Priv> for u8 {}
    impl TraitWithAssocTy for u8 { type AssocTy = Priv; }
    //~^ ERROR private type `Priv` in public interface

    pub fn leak_anon1() -> impl Trait + 'static { 0 }
    pub fn leak_anon2() -> impl TraitWithTyParam<Alias> { 0 }
    pub fn leak_anon3() -> impl TraitWithAssocTy<AssocTy = Alias> { 0 }

    pub fn leak_dyn1() -> Box<dyn Trait + 'static> { Box::new(0) }
    pub fn leak_dyn2() -> Box<dyn TraitWithTyParam<Alias>> { Box::new(0) }
    pub fn leak_dyn3() -> Box<dyn TraitWithAssocTy<AssocTy = Alias>> { Box::new(0) }
}

mod adjust {
    // Construct a chain of derefs with a private type in the middle
    use std::ops::Deref;

    pub struct S1;
    struct S2;
    pub type S2Alias = S2;
    pub struct S3;

    impl Deref for S1 {
        type Target = S2Alias; //~ ERROR private type `S2` in public interface
        fn deref(&self) -> &Self::Target { loop {} }
    }
    impl Deref for S2 {
        type Target = S3;
        fn deref(&self) -> &Self::Target { loop {} }
    }

    impl S3 {
        pub fn method_s3(&self) {}
    }
}

fn main() {
    let _: m::Alias; //~ ERROR type `Priv` is private
                     //~^ ERROR type `Priv` is private
    let _: <m::Alias as m::TraitWithAssocTy>::AssocTy; //~ ERROR type `Priv` is private
    m::Alias {}; //~ ERROR type `Priv` is private
    m::Pub { 0: m::Alias {} }; //~ ERROR type `Priv` is private
    m::Pub { 0: loop {} }; // OK, `m::Pub` is in value context, so it means Pub<_>, not Pub<Priv>
    m::Pub::static_method; //~ ERROR type `Priv` is private
    m::Pub::INHERENT_ASSOC_CONST; //~ ERROR type `Priv` is private
    m::Pub(0u8).method_with_substs::<m::Alias>(); //~ ERROR type `Priv` is private
    m::Pub(0u8).method_with_priv_params(loop{}); //~ ERROR type `Priv` is private
    <m::Alias as m::TraitWithAssocConst>::TRAIT_ASSOC_CONST; //~ ERROR type `Priv` is private
    <m::Pub<m::Alias>>::INHERENT_ASSOC_CONST; //~ ERROR type `Priv` is private
    <m::Pub<m::Alias>>::INHERENT_ASSOC_CONST_GENERIC_SELF; //~ ERROR type `Priv` is private
    <m::Pub<m::Alias>>::static_method_generic_self; //~ ERROR type `Priv` is private
    use m::TraitWithTyParam2;
    u8::pub_method; //~ ERROR type `Priv` is private

    adjust::S1.method_s3(); //~ ERROR type `S2` is private

    m::m!();

    m::leak_anon1(); //~ ERROR trait `Trait` is private
    m::leak_anon2(); //~ ERROR type `Priv` is private
    m::leak_anon3(); //~ ERROR type `Priv` is private

    m::leak_dyn1(); //~ ERROR trait `Trait` is private
    m::leak_dyn2(); //~ ERROR type `Priv` is private
    m::leak_dyn3(); //~ ERROR type `Priv` is private

    // Check that messages are not duplicated for various kinds of assignments
    let a = m::Alias {}; //~ ERROR type `Priv` is private
    let mut b = a; //~ ERROR type `Priv` is private
    b = a; //~ ERROR type `Priv` is private
    match a { //~ ERROR type `Priv` is private
        _ => {}
    }
}