diff options
Diffstat (limited to 'src/test/ui/privacy/private-inferred-type.rs')
-rw-r--r-- | src/test/ui/privacy/private-inferred-type.rs | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/test/ui/privacy/private-inferred-type.rs b/src/test/ui/privacy/private-inferred-type.rs new file mode 100644 index 000000000..b083a3970 --- /dev/null +++ b/src/test/ui/privacy/private-inferred-type.rs @@ -0,0 +1,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 + _ => {} + } +} |