diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index cf32f237b8676..30c5666a057e4 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -1302,6 +1302,27 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> { return; } + match pattern.kind { + hir::PatKind::TupleStruct(qpath, ..) => { + // Tuple struct constructors have to be checked specially. + self.span = qpath.span(); + let def_id = match qpath { + hir::QPath::Resolved(_, path) => path.res.opt_def_id(), + hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self + .maybe_typeck_results + .unwrap_or_else(|| span_bug!(self.span, "`hir::Pat` outside of a body")) + .type_dependent_def_id(pattern.hir_id), + }; + + if let Some(def_id) = def_id { + if self.visit(self.tcx.type_of(def_id).instantiate_identity()).is_break() { + return; + } + } + } + _ => {} + } + intravisit::walk_pat(self, pattern); } diff --git a/tests/ui/privacy/private-in-public-tuple-struct-pat.rs b/tests/ui/privacy/private-in-public-tuple-struct-pat.rs new file mode 100644 index 0000000000000..ee02c049669b5 --- /dev/null +++ b/tests/ui/privacy/private-in-public-tuple-struct-pat.rs @@ -0,0 +1,36 @@ +mod m { + struct Priv; + + #[allow(private_interfaces)] + pub struct PubStruct(pub Priv); + pub enum PubEnum { + #[allow(private_interfaces)] + Variant(Priv), + } + + impl PubStruct { + pub fn new() -> PubStruct { + PubStruct(Priv) + } + } + impl PubEnum { + pub fn new() -> PubEnum { + PubEnum::Variant(Priv) + } + } +} + +fn main() { + match m::PubStruct::new() { + m::PubStruct(_) => {} //~ ERROR type `Priv` is private + m::PubStruct(..) => {} //~ ERROR type `Priv` is private + } + + match m::PubEnum::new() { + m::PubEnum::Variant(_) => {} //~ ERROR type `Priv` is private + m::PubEnum::Variant(..) => {} //~ ERROR type `Priv` is private + } + + let _ = m::PubStruct; //~ ERROR type `Priv` is private + let _ = m::PubEnum::Variant; //~ ERROR type `Priv` is private +} diff --git a/tests/ui/privacy/private-in-public-tuple-struct-pat.stderr b/tests/ui/privacy/private-in-public-tuple-struct-pat.stderr new file mode 100644 index 0000000000000..847ddc3d04d44 --- /dev/null +++ b/tests/ui/privacy/private-in-public-tuple-struct-pat.stderr @@ -0,0 +1,38 @@ +error: type `Priv` is private + --> $DIR/private-in-public-tuple-struct-pat.rs:25:9 + | +LL | m::PubStruct(_) => {} + | ^^^^^^^^^^^^ private type + +error: type `Priv` is private + --> $DIR/private-in-public-tuple-struct-pat.rs:26:9 + | +LL | m::PubStruct(..) => {} + | ^^^^^^^^^^^^ private type + +error: type `Priv` is private + --> $DIR/private-in-public-tuple-struct-pat.rs:30:9 + | +LL | m::PubEnum::Variant(_) => {} + | ^^^^^^^^^^^^^^^^^^^ private type + +error: type `Priv` is private + --> $DIR/private-in-public-tuple-struct-pat.rs:31:9 + | +LL | m::PubEnum::Variant(..) => {} + | ^^^^^^^^^^^^^^^^^^^ private type + +error: type `Priv` is private + --> $DIR/private-in-public-tuple-struct-pat.rs:34:13 + | +LL | let _ = m::PubStruct; + | ^^^^^^^^^^^^ private type + +error: type `Priv` is private + --> $DIR/private-in-public-tuple-struct-pat.rs:35:13 + | +LL | let _ = m::PubEnum::Variant; + | ^^^^^^^^^^^^^^^^^^^ private type + +error: aborting due to 6 previous errors +