diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index ee459d9c129d3..86244aa8985e8 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -775,7 +775,14 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } // Corner case: if the variant is reachable, but its // enum is not, make the enum reachable as well. - self.update(item.def_id, variant_level); + self.reach(item.def_id, variant_level).ty(); + } + if let Some(hir_id) = variant.data.ctor_hir_id() { + let ctor_def_id = self.tcx.hir().local_def_id(hir_id); + let ctor_level = self.get(ctor_def_id); + if ctor_level.is_some() { + self.reach(item.def_id, ctor_level).ty(); + } } } } @@ -803,6 +810,13 @@ impl<'tcx> Visitor<'tcx> for EmbargoVisitor<'tcx> { } } } + if let Some(hir_id) = struct_def.ctor_hir_id() { + let ctor_def_id = self.tcx.hir().local_def_id(hir_id); + let ctor_level = self.get(ctor_def_id); + if ctor_level.is_some() { + self.reach(item.def_id, ctor_level).ty(); + } + } } } diff --git a/src/test/ui/privacy/auxiliary/ctor_aux.rs b/src/test/ui/privacy/auxiliary/ctor_aux.rs new file mode 100644 index 0000000000000..9c99cca9ae6ed --- /dev/null +++ b/src/test/ui/privacy/auxiliary/ctor_aux.rs @@ -0,0 +1,25 @@ +// edition:2021 +//! Missing docs lint warns about undocumented exported items. +//! Use the lint to additionally verify that items are reachable +//! but not exported. +#![allow(non_camel_case_types)] +#![deny(missing_docs)] + +mod hidden { + pub struct s; + pub enum e { x, y, z } + pub use e::*; + impl s { + pub fn f(&self) {} + } + impl e { + pub fn g(&self) {} + } +} +// Hide all type definitions while reexporting their constructors: +mod e {} +mod x {} +mod y {} +mod z {} +mod s {} +pub use hidden::*; diff --git a/src/test/ui/privacy/ctor.rs b/src/test/ui/privacy/ctor.rs new file mode 100644 index 0000000000000..0ec15d68ed39e --- /dev/null +++ b/src/test/ui/privacy/ctor.rs @@ -0,0 +1,16 @@ +// Verify that a type is considered reachable when its constructor is +// reachable. The auxiliary library is constructed so that all types are +// shadowed and cannot be named directly, while their constructors are +// reexported. Regression test for issue #96934. +// +// aux-build:ctor_aux.rs +// edition:2021 +// build-pass + +extern crate ctor_aux; + +fn main() { + ctor_aux::s.f(); + ctor_aux::x.g(); + ctor_aux::y.g(); +}