summaryrefslogtreecommitdiffstats
path: root/src/test/ui/privacy/private-inferred-type.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ui/privacy/private-inferred-type.rs')
-rw-r--r--src/test/ui/privacy/private-inferred-type.rs133
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
+ _ => {}
+ }
+}